Place Meeting and Mask Index

N

Nabil Kabour

Guest
I'm using place_meeting to do collisions for a side scrolling platformer. When I set the mask_index of one of the platforms to -1, the collision is still registered. What is going on?
 

TheouAegis

Member
It's using the sprite's mask. The mask_index is just a secondary bounding box that overrides the default one. Setting mask_index to -1 is pretty useless imho.
 
N

Nabil Kabour

Guest
It's using the sprite's mask. The mask_index is just a secondary bounding box that overrides the default one. Setting mask_index to -1 is pretty useless imho.
Why is it using the sprite's mask though? What would be the correct way of doing it? I tried setting the sprite_index = -1 in the create event, and then setting mask_index = -1 or mask_index to the object sprite and it works. I got this approach from a video of Shaun Spalding.
Doesn't look clean at all though. I can imagine some scenarios where I'd need to modify an instance's mask at runtime and check for collisions. How would I do that as well?
 

TheouAegis

Member
The correct way is to not mess with either one. The correct way is to stop the player when he's moving down and coming at the platform from above. Shaun's tutorial on one-way platforms is crap.

When vspeed is less than 0, only look for collisions with solid platforms. When vspeed is greater than 0, look for collisions with all platforms.
 

Slyddar

Member
The method Shaun uses for one way platforms in that video is exceptionally bad. It doesn't take into account if an enemy is on the platform at all. There are much better ways of doing it inside the collision code instead of altering masks.
 
N

Nabil Kabour

Guest
The correct way is to not mess with either one. The correct way is to stop the player when he's moving down and coming at the platform from above. Shaun's tutorial on one-way platforms is crap.

When vspeed is less than 0, only look for collisions with solid platforms. When vspeed is greater than 0, look for collisions with all platforms.
Haha. Yeah that's for standard collisions. What about one way, when the player is moving up and under the platform?
 
N

Nabil Kabour

Guest
The method Shaun uses for one way platforms in that video is exceptionally bad. It doesn't take into account if an enemy is on the platform at all. There are much better ways of doing it inside the collision code instead of altering masks.
Can you describe to me one way, just so I get an idea?
 

TheouAegis

Member
I did. When vspeed is less than 0, you look for collisions with only the solid platforms. When vspeed is greater than 0, you look for collisions with all platforms. If you find a collision with a solid platform while moving down, then stop checking for collisions, since you found one. But if there's no solid platform under you, look for a one-way platform. If there is one, check that your bbox_bottom is less than the top of the platform before colliding with it.
 

Bentley

Member
Can you describe to me one way, just so I get an idea?
Code:
// Pseudo code
if (collision_with_oneway y + vspd)
{
    if (vspd > 0)
    {
        if (bbox_bottom < oneway.bbox_top)
        {
            y = oneway.bbox_top - sprite_yoffset - 1;
        }
    }
}
Something like that. I have not worked on a platformer in a while, but I remember using a 1 px high object and stretch its image_xscale and place isntances in the room editor over the top of the tiles.
 
Last edited:
N

Nabil Kabour

Guest
Code:
// Pseudo code
if (collision_with_oneway y + vspd)
{
    if (vspd > 0)
    {
        if (bbox_bottom < oneway.bbox_top)
        {
            y = oneway.bbox_top - sprite_yoffset - 1;
        }
    }
}
Something like that. I have not worked on a platformer in a while, but I remember using a 1 px high object and stretch its image_xscale and place isntances in the room editor over the top of the tiles.
I've thought of some ideas. But yeah the most obvious one that comes to mind is using the sign of vspd to check if to collide with the one way or not. The trouble with your code is that when the player is moving down he will instantly be moved onto the platform. I'll post some code later on, I'm working on something else at the moment, and I want to finish it before working on continuing on other things.
 

Slyddar

Member
Here's a copy of some code I've used in the past. Not sure if it's the best way to do it, but I've used it for platforms and it works fine. Happy to hear from others if they have a better way.
  • o_wall is a solid block
  • o_wallp is a platform block
  • They are both children of the o_wall_parent object.

Code:
// Horizontal Collision
if  (place_meeting(x + hsp, y, o_wall) and !place_meeting(x + hsp, y, o_wallp)) or
    ((place_meeting(x + hsp, y, o_wallp) and vsp > 0) and !place_meeting(x, y, o_wallp)) {
    while !place_meeting(x + sign(hsp), y, o_wall_parent) { 
        x += sign(hsp);
    }
    hsp = 0;
}
x += hsp;

// Vertical collision
// if collision with wall and not collision with platform, or
// collision with platform next step and vsp > 0, but not collision with platform this step, then stop
if  (place_meeting(x, y + vsp, o_wall) and !place_meeting(x, y + vsp, o_wallp)) or
    ((place_meeting(x, y + vsp, o_wallp) and vsp > 0) and !place_meeting(x, y, o_wallp)) {
    while !place_meeting(x, y + sign(vsp), o_wall_parent) {
        y += sign(vsp);
    }
    vsp = 0;
}
y += vsp;
 

Bentley

Member
The trouble with your code is that when the player is moving down he will instantly be moved onto the platform.
I don't think so. You are checking y + vspd away which is where you will end up in this frame. So if there is a oneway you are about to collide with, and you are above the oneway, you snap to it.
 
Top