# Grabbing ledge with tilebased collisions

#### White_Fox

##### Member
Hello everyone,
i'm following a course on Udemy on creating a tilebased platformer.
For my personal project, i'm trying to create a tilebased platformer with a parkour"ish" vibe.
I've manage to add a "grab ledge" state and it's working well on some aspects, but i'm not 100% satisfied on how it goes right now.
So, i'll post my code below and maybe someone can enlight me on finishing it.

This is the code in my collision script. I've highlighted it in green. As I said above, i've took it from a course i'm following on Udemy and added some other part to get a collision detection for the ledges.
Right now, my character can grab the ledge but, it's doesn't just take the corner of the ledges. My player (o_player) takes the height of a tile size depending on where it lands when grabbing the ledge. So my question is: how can my grab ledge collision code can work for only detecting the top corner of my tile name SOLID?
Also, I was wondering if it was okay to put in front in term of priority instead of putting it after the horizontal and vertical collision code?

------------------------------------------

/// collision();
if hsp == 0 hsp_decimal = 0;
if vsp == 0 vsp_decimal = 0;

//apply carried over decimals
hsp += hsp_decimal;
vsp += vsp_decimal;

//floor decimals
//save and substract decimals
hsp_decimal = hsp - (floor(abs(hsp)) * sign(hsp));
hsp -= hsp_decimal;
vsp_decimal = vsp - (floor(abs(vsp)) * sign(vsp));
vsp -= vsp_decimal;

//check ledge
var side
var top_bottom
if hsp > 0 side = bbox_right else side = bbox_left;
if vsp > 0 top_bottom = bbox_top else top_bottom = bbox_bottom ;

var t1 = tilemap_get_at_pixel(global.map, side + vsp, bbox_bottom); //test corner up
var t2 = tilemap_get_at_pixel(global.map, side + vsp, bbox_top) ; //test corner down
var t3 = tilemap_get_at_pixel(global.map, x, bbox_bottom + (global.tile_size * 1.5)); // minimal height before grabbing ledge
var t4 = tilemap_get_at_pixel(global.map, side + vsp, bbox_top + global.tile_size); //

if (t1 == SOLID)
and (t2 == VOID)
and (t3 != SOLID) and (t3 != PLATFORM) and (t3 == VOID)
and (t4 == VOID)
{
//ledge found;

y = bbox_top + global.tile_size
state = states.GRAB_LEDGE;
hsp = 0;
vsp = 0;

}

//horizontal collision
var side;
//determine which side to test
if hsp > 0 side = bbox_right else side = bbox_left;

//check top and bottom of side
var t1 = tilemap_get_at_pixel(global.map, side + hsp, bbox_top);
var t2 = tilemap_get_at_pixel(global.map, side + hsp, bbox_bottom);
var t3 = tilemap_get_at_pixel(global.map, side + vsp, bbox_top);
var t4 = tilemap_get_at_pixel(global.map, side + vsp, bbox_bottom);

if ((t1 != VOID) and (t1 != PLATFORM)) or
((t2 != VOID) and (t2 != PLATFORM)) {
//collision found
if (hsp > 0) x = x - (x mod global.tile_size) + global.tile_size - 1 - (side - x)
else x = x - (x mod global.tile_size) - (side - x);
hsp = 0;
}

x +=hsp;

//vertical collision

var side;
//determine which side to test
if vsp > 0 side = bbox_bottom else side = bbox_top;

//check left and right side
var t1 = tilemap_get_at_pixel(global.map, bbox_left, side + vsp);
var t2 = tilemap_get_at_pixel(global.map, bbox_right, side + vsp);
var t3 = tilemap_get_at_pixel(global.map, bbox_left, bbox_bottom);
var t4 = tilemap_get_at_pixel(global.map, bbox_right, bbox_bottom);

if (t1 != VOID and (((vsp > 0 or t1 !=PLATFORM)) and t3 != PLATFORM) or (t1 == SOLID and t3 == PLATFORM)) or
(t2 != VOID and (((vsp > 0 or t2 !=PLATFORM)) and t4 != PLATFORM) or (t2 == SOLID and t4 == PLATFORM)) {
//collision found
if (vsp > 0) y = y - (y mod global.tile_size) + global.tile_size - 1 - (side - y)
else y = y - (y mod global.tile_size) - (side - y);
vsp = 0;

}

y +=vsp;

------------------------

Hope someone can help me out with this!

Thanks