Legacy GM One Way Platforms --> collision checking

NoFontNL

Member
Hi, I experienced problems with collison checking with one way platforms:
GIF: https://i.imgur.com/wYEeo0i.gif

This is my code:
Code:
// Jump code:
if (keyJump and
    (place_meeting(x,y+1,par_ground)or
        (place_meeting(x,y+1,obj_oneway) and
        vsp >=0))) {
    vsp =  -jSpeed
}
// Collison checking code, first ground, then checks for platform.
if (place_meeting(x,y+vsp,par_ground)) {
    while (!place_meeting(x,y+sign(vsp),par_ground)) {
       y+= sign(vsp);
    }
    vsp = 0
}
with (obj_oneway)
{
    //if player is above it
    if (other.bbox_bottom <= bbox_top)
    {
        //collision checks with player (other)
            if (instance_place(x,y-other.vsp,other)) {
                    while (!place_meeting(x,y-1,other)) {
                        other.y+= 1;
                    }
                    other.vsp = 0
            }
      
    }
}
y+=vsp;
But as you see on the gif, sometimes, there's a little space between the player and the platform, so there's no platform 1 pixel below me, so I can't jump. What do I do wrong? The par_ground works fine, as you see on the GIF. When I am 2 pixels above the one way platform, and I'm a little above the grass, I am 1 pixel above the grass. If you cannot follow me there, here's the scenario:

1. I jump on the one way platform and sometimes I land 1 pixel above the platform, but sometimes also 2 pixels.
2. I can't jump when I'm 2 pixels above the platform, because it checks for 1 pixel below me. (see jump code)
3. When I'm still 2 pixels above the platform, and I'm 1 or more pixels above the grass, I 'fall' and land perfectly on the grass.
4. But when I'm not above the grass and when I'm 2 pixels above the platform, I can't 'fall' down to land on the platform, which is working with the grass.
 
Last edited:

Bentley

Member
My first thought is that your moving at sub-pixels. So, for ex, if you're 0.9 pixels away from the oneway, you won't move. What does your gravity code look like?

People have clever ways of dealing with sub-pixels. I don't. I'd just: var vspd_int = round(vspd); And then plug vspd_int into the collision code. You'd then set the real vspd to 0 when there's a collision.
 

NoFontNL

Member
My first thought is that your moving at sub-pixels. So, for ex, if you're 0.9 pixels away from the oneway, you won't move. What does your gravity code look like?

People have clever ways of dealing with sub-pixels. I don't. I'd just: var vspd_int = round(vspd); And then plug vspd_int into the collision code. You'd then set the real vspd to 0 when there's a collision.
Gravity code:
Code:
grav = 1.5; // (create event)
if (vsp < 20 ) vsp+=grav; // (step event)
 
Last edited:

Bentley

Member
Well, then yeah, I think you may be stopping 0.5 pixels above the platform. The code won't move you down that distance because
"while (!place_meeting(x, y - 1, other))"
won't run, as there is a place meeting y - 1 away (the player is 0.5 away).

I could be wrong. I tried to come up with something to help you using your code, but it was kind of hard, sorry. All those "others" haha. I'd be glad to show you how I'd do it, just ask.
 

Bentley

Member
Edit: The simplest way would be to just snap to the onway's bbox_top - 1. Ok, nuff said. Good luck.

So what should I do?
I would round "vsp" before the collision check. This is how I'd do it, starting from where you commented "collision checking code":

Step Event
Code:
var vsp_int = round(vsp);

repeat (abs(vsp_int))
{
    if (!place_meeting(x, y + sign(vsp_int), par_solid) && !collision_with_oneway())
    {
        y += sign(vsp_int);  
    }
    else
    {
        vsp = 0;
        break;
    }
}
collision_with_oneway script
Code:
return (vsp > 0 && place_meeting(x, y + 1, obj_oneway) && !place_meeting(x, y, obj_oneway))
-collision_with_oneway checks if you're about to collide with a oneway: you have to be falling, you have to be about to collide with the oneway, and you can't be inside the oneway.
 
Last edited:

NoFontNL

Member
I would round "hsp" before the collision check. This is how I'd do it, starting from where you commented "collision checking code":

Step Event
Code:
var vsp_int = round(vsp);

if (!place_meeting(x, y + vsp_int, par_ground) && !collision_with_oneway())
{
    y += vsp_int;
}
else
{
    vsp = 0;
 
    do
    {
        y += sign(vsp_int);
    }
    until (standing());
}
collision_with_oneway script
Code:
return (vsp > 0 && place_meeting(x, y + vsp, obj_oneway) && !place_meeting(x, y, obj_oneway))
standing script
Code:
return ( place_meeting(x, y + 1, par_ground) || (vsp == 0 && place_meeting(x, y + 1, obj_oneway)) );
And what is standing() ? What's inside that script?
 

TheouAegis

Member
As Bentley said, just snap the player to the plat. You already know the player is going to collide with a platform, so there is no point in moving the player repeatedly one pixel at a time until it comes into contact and Theory with the platform. If you do not have the player's y coordinate placed below bbox_bottom, then you can snap via

other.y += bbox_top - other.bbox_bottom;

Or, like, something similar. Then set vsp to 0.
 
Top