GMS 2 Precise collisions (2 place_meeting statements cancelling each other out)

Roobicorn

Member
I'm working on a platformer in which involves the player being able to jump up through ledges, landing on top of them, or, if they can reach the ledge but can't make it over, they can grab the ledge and hang from it.

I'm expanding on some of the code from Shaun Spalding's Platformer tutorial.
I'm using !place_meeting(x, y+1, obj_ledge) to ensure that the player is in the air & not standing on a ledge, and place_meeting(x, y, obj_ledge) to detect if the player is colliding with a ledge he can grab.

Code:
on_ledge = place_meeting(x, y + 1, obj_ledge);

over_ledge = place_meeting(x, y, obj_ledge);

(...)

    //GRABBING LEDGE:
    if (!on_ledge && over_ledge && key_up_held)
    {
        var _ledge = instance_place(x, y, obj_ledge);
        to_y = _ledge.y + 8;
        if (y >= to_y)
        {
            y = to_y;
            state = HANGING;
        }
    }
The problem I'm having is that (if I understand it correctly) !place_meeting(x, y+1 ...) doesn't just check the row of pixels below the object, it checks the whole collision mask, moved down by one pixel.
so when combined with place_meeting(x, y ...), this means that the check only returns true if the top row of pixels in the collision mask collides with the object. (see image):

upload_2019-9-7_11-37-51.png


This is ok some of the time, but often, these pixels might not collide with the ledge depending on the speed and direction of the jump, or if the player's timing is off. and it means that the player cannot grab onto a ledge if it's at, say, his eye-level.

Is there a way I can both ensure there's no ledge-collision from below, while checking for a collision with at least the top-half of the player object?
 
Last edited:
as for the collision below, collision_line simply use x+ and y+ to state the position, this makes the on the ground to a single pixel wide collision line directly under the player if done right leaving the entire player sprite for your other check.
 

Roobicorn

Member
as for the collision below, collision_line simply use x+ and y+ to state the position, this makes the on the ground to a single pixel wide collision line directly under the player if done right leaving the entire player sprite for your other check.
This is a good idea. so something like collision_line( x - half_sprite_width , y + half_sprite_height , x + half_sprite_width , y + half_sprite_height , obj, false, false) ?
Thanks, I'll give it a go...

EDIT:
yep, I tried the following (and added a draw_line with the same co-ordinates in the draw step to make sure I got the co-ords right) and seems to work fine. Thanks @spoonsinbunnies

Code:
on_ledge = collision_line(x - half_spr_width, y + half_spr_height,
                            x + half_spr_width, y + half_spr_width,
                            obj_ledge, false, false);
 
Last edited:
Top