Dumb Question about collision

I haven't touched GML in a long time, and it seems my memory is faulty.

I'm doing a simple movement system, just a prototype at the moment, but the collision doesn't seem to register how i would expect.

the code I'm using is

if !place_meeting(x+2,y,obj_stone) {x+=2}

I was under the impression that if any part of the collision masks were to overlap, this would count as a collision. Both sprites are 16 by 16 boxes, meaning that there should be at least 8 distinct positions where the collision event stops horizontal movement from top to bottom, movement always occurring in increments of 2, but for some reason collision only registers when the blocks are at identical vertical values, so... somehow, the collision is entirely ignored and passing through solid objects is allowed in every other vertical position. I've tried using several other methods, but seem to have similar problems. What am I missing? Any insight would be very helpful.
 

TheouAegis

Member
Make sure you don't have a mask_index set. Make sure the collision box is set to Full Image in both sprites. If it's set to Automatic and one sprite has a lot of pixels with 0 alpha around it, the collision box will be smaller than 16x16; setting it to Full Image will set the mask to cover the entire sprite. Make sure both sprites thus actually do have 16x16 collision boxes.
 
Where do I find those settings? I saw them on a few tutorial videos, but they don't seem to be there on mine,.is there some setting that dumbs downy options that I don't know about?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Where do I find those settings? I saw them on a few tutorial videos, but they don't seem to be there on mine,.is there some setting that dumbs downy options that I don't know about?
What version of GM are you using? In GMS2 the options for collision masks are in the Sprite Editor, on the left, in the section marked "Collision Mask": https://manual.yoyogames.com/The_Asset_Editors/Sprites.htm

Setting the collision mask on the sprite means that any object with that sprite attached will base it's collisions on that mask. HOWEVER you can also override this mask by setting the "mask index" on the object either by code (using the mask_index variable) or in the IDE by setting the Collision Mask to a different setting: https://manual.yoyogames.com/The_Asset_Editors/Objects.htm

If you set the collision mask of an object to use a different sprite, then instances of the object will DRAW the assigned sprite, but base collisions off of the sprite assigned to the collision mask.
 
What version of GM are you using? In GMS2 the options for collision masks are in the Sprite Editor, on the left, in the section marked "Collision Mask": https://manual.yoyogames.com/The_Asset_Editors/Sprites.htm

Setting the collision mask on the sprite means that any object with that sprite attached will base it's collisions on that mask. HOWEVER you can also override this mask by setting the "mask index" on the object either by code (using the mask_index variable) or in the IDE by setting the Collision Mask to a different setting: https://manual.yoyogames.com/The_Asset_Editors/Objects.htm

If you set the collision mask of an object to use a different sprite, then instances of the object will DRAW the assigned sprite, but base collisions off of the sprite assigned to the collision mask.
I'm using the current version, and I haven't set any index, I have indicated a mask for collision, which is a 16 by 16 box with no transparent pixels at all

What version of GM are you using? In GMS2 the options for collision masks are in the Sprite Editor, on the left, in the section marked "Collision Mask": https://manual.yoyogames.com/The_Asset_Editors/Sprites.htm

Setting the collision mask on the sprite means that any object with that sprite attached will base it's collisions on that mask. HOWEVER you can also override this mask by setting the "mask index" on the object either by code (using the mask_index variable) or in the IDE by setting the Collision Mask to a different setting: https://manual.yoyogames.com/The_Asset_Editors/Objects.htm

If you set the collision mask of an object to use a different sprite, then instances of the object will DRAW the assigned sprite, but base collisions off of the sprite assigned to the collision mask.
Okay, I set the second sprite, a box, as the mask in the object settings, which is configured to use the full age as a rectangle, or square in this case.

Okay, I guess I wasn't clear enough, so here is clarification. I had set the masks to simple 16 x 16 squares, full image. Still, collision was not working, at all. So I cloned the objects, removed any masks and simply made the basic sprites 16 x 16 squares. Still, the collision is wonky, even with the collision mask being set to "same as sprite" which is a simple 16 by 16 square. The exact problem i seem to be having, is that the collision only registers on one pixel. When moving vertically, collision only registers when the horizontal value is exactly the same. Similarly, when moving horizontally, the collision only registers when the vertical value is the same. Even more bizarrely, the majority of the block doesn't count any collision at all, only the area near the origin point, a single pixel it seems, will actually stop movement. I still have not managed to figure out what on earth is happening.

if keyboard_check(vk_up)
{
if !place_meeting(x,y-2,obj_stone){y-=2}
}
if keyboard_check(vk_right)
{
if !place_meeting(x+18,y,obj_stone){x+=2}
}
if keyboard_check(vk_down)
{
if !place_meeting(x,y+18,obj_stone){y+=2}
}
if keyboard_check(vk_left)
{
if !place_meeting(x-2,y,obj_stone){x-=2}
}

Here is the complete length of code as it currently exists. I know it's simple, but that's what makes the problem so egregious. What am I missing?
 

Tony Brice

Member
As above. What you should have is a variable with the increment value of how many pixels you are moving and then check that far ahead each frame. When you get a positive hit then you can not allow movement any further in that direction and then do a while loop to move the object 1 pixel in that direction until it can't move any further.
 
As above. What you should have is a variable with the increment value of how many pixels you are moving and then check that far ahead each frame. When you get a positive hit then you can not allow movement any further in that direction and then do a while loop to move the object 1 pixel in that direction until it can't move any further.
I always use origin points in the top left corner, and in this instance I'm moving forward by only two pixels each frame. As such, sprite width of 16, 2 pixels, 18
 
You don't know what place_meeting does, do you?
I guess not. I thought it checked for overlap of the collision masks of the current instance with the indicated instance. Have I misunderstood?
*Edit* Well I would like to apologize for anyone's time that I wasted, as I found the problem exploring an earlier solution. Even though the collision masks were set to full image, only a single pixel was actually being checked. When I manually changed the bounding boxes to encompass the entire square, all of my issues were cleared up. Thank you everyone for your help, I couldn't feel sillier
 
Last edited:

Nidoking

Member
I thought it checked for overlap of the collision masks of the current instance with the indicated instance.
It says "if I put myself at this x and y position, will I collide with the indicated instance/an instance of the indicated object?" Adding the sprite width means that you're placing the instance one additional width to the right, so it isn't overlapping the position where you want to check it at all.
 
Top