Legacy GM Platform Collision Question[Solved]

P

Preston

Guest
Hey all, new here to Game Maker here (studio version). I've been just following some tutorials from Shaun Spalding and a few others. I've got an issue with collisions that's throwing me for a loop (due to inexperience).

TLDR down below.

Basically I took the one way platforms and removed the function of dropping through them. From there I want them to be fully solid not allowing anything to pass through them including my player.

However, what's happening is not the case. If I'm on the moving platform it carries me like normal, and I cannot drop through it like planned. If I fall off of it and collide with the side it will push me like intended, however, if I move left (assuming I fell off the right side of the platform which is also moving right) I just get stuck in mid air as the platform passes through me. Once it's fully through me I drop.

So something is happening when I use an input to move left or right while colliding with the sides of the platform.

Here's a sample of my char just standing on the ground. If I don't move as the platform collides with me it will push me like normal. But I pushed left here, which freezes my char in place while the platform moves through it.

Collision.png

I would like to figure this out before I move forward :) plans to create different pushing devices (traps).

Here's my players step events (tutorial's basically)
Code:
//Get the player's inputs (what is being pushed)
key_right = keyboard_check(vk_right);
key_left = -keyboard_check(vk_left);
key_jump = keyboard_check_pressed(vk_space);
key_down = keyboard_check(vk_down);


//React to inputs
move = key_left + key_right;
hsp = move * movespeed;
if (vsp < 10) vsp += grav;

if (place_meeting(x,y+1,obj_ground))
    {
        if (key_jump) vsp = -jumpspeed;
    }
    
var hsp_final = hsp + hsp_carry;
hsp_carry = 0;
    
//Horizontal Collision
if (place_meeting(x+hsp_final,y,obj_ground))
{
    while(!place_meeting(x+sign(hsp_final),y,obj_ground))
    {
        x += sign(hsp_final);
    }
    hsp_final = 0;
    hsp = 0;
} 
x += hsp_final;

//Vertical Collision
if (place_meeting(x,y+vsp,obj_ground))
{
    while(!place_meeting(x,y+sign(vsp),obj_ground))
    {
        y += sign(vsp);
    }
    vsp = 0;
} 
var vsp_final = vsp + vsp_carry;
vsp_carry = 0;
y += vsp;

//Animate
if (move!=0) image_xscale = move;
if (place_meeting(x,y+1,obj_ground))
{
    if (hsp!=0) sprite_index = spr_walk; else sprite_index = spr_idle;
    image_speed = .25;
}
else
{
    if (vsp < 0) sprite_index = spr_jump; else sprite_index = spr_fall
    image_speed = .25;
}
I'm not a programmer so I'm not going to pretend I fully understand everything here, but I get the gist of it.

Here's my platforms:
Code:
//movement
image_speed = .25;
hsp = dir * movespeed;



//Horizontal Collision
if (place_meeting(x+hsp,y,obj_ground))
{
    while(!place_meeting(x+sign(hsp),y,obj_ground))
    {
        x += sign(hsp);
    }
    hsp = 0;
    
    dir *= -1;
} 
x += hsp;



if (instance_exists(obj_player))
{

        if place_meeting(x,y-1,obj_player)
        {
            obj_player.hsp_carry = hsp;
        }

}
I don't believe it's a collision mask issue as I spent a lot of time getting everything perfectly centered with all my animations with no collision mask offset from any input.

I want to assume there's something simple I'm missing or have not yet learned/fully understand that will fix my issue. Maybe something along the line of adding a new place_meeting with x's (account for vsp/grav/hsp)? If anyone has an idea I would appreciate it!

Off for the day but will check back later, thanks in advance!

TLDR: Collision with platforms sides freeze my player when an input is issued, allowing the platform to move by while my character is stuck. Need help understanding how to make the sides push my player no matter what.
 

TheouAegis

Member
The freezing is simple. The player's hsp vector is greater than the hsp_carry vector, so ultimately the player looks for a collision in the direction of hsp. There is one - the platform - so the player's hsp_final is set to 0, stopping the player. Then the platform moves over a bit. The player looks for a collision in the direction of hsp again. There is one, so hsp_final is set to 0 yet again. Then the platform moves over a bit more. Now the player is so far in the platform that it doesn't matter which vector is greater - no matter which direction the player tries to move, he'll be so far in the platform that a collision will be detected and hsp_final is set to 0 every time; in other words, the player freezes in place. You could actually move out of the collision if you walked in the direction the platform was moving soon enough after getting stuck.

With that said, you should consider only setting hsp_carry when the player is actually above the platform. That is not what your platform's code is doing. Your platform is checking if any part of the player is above the bottom of the platform. This is one of the drawbacks to place_meeting(). I prefer a collision check like:

with obj_player {
if bbox_left < other.bbox_right && bbox_right > other.bbox_left {
if bbox_bottom == other.bbox_top - 1
hsp_carry = other.hsp;​
else
if bbox_top < other.bbox_bottom && bbox_bottom > other.bbox_top {
x += other.hsp;
if place_meeting(x,y,obj_ground)
// Kill the player because he got squished​
}​
}

As you can see, I added a consideration for the platforms squishing the player against a wall and killing him.

The only concern I have with this code without testing it myself is if two platforms cross paths while the player is on the lower one.
 
P

Preston

Guest
That makes sense, thank you for explaining it! So by the time my players movement is checked in it's last state it's already too late. I could see how that's a drawback of using the place_meeting(). That's really cool work around and works just as presented. It does come across an issue when two platforms cross paths but I can work around that simply by avoiding such scenarios which isn't a big deal.

Thanks for introducing me to these! Appreciate the help.
 
Top