• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker zelda 4 style collision in a platformer game

S

Shadowblitz16

Guest
can somebody tell me how to achieve zelda 4 style collision in a mario game?
basicly that way zelda 4 collision worked is it only stopped if the player from walking into solid walls if there was a collision right next to him

so something like this... https://drive.google.com/open?id=0B16wNFPwi_2keF9zdUtMemxWclE

you would think that this wouldn't work if the player was going to fast or was not aligned to the pixel but in fact
this wasn't a problem because he was already aligned to the pixel and his position was incremented 1 pixel at a time in a loop similar to this..
Code:
var next_step = point_distance(xprevious, yprevious, x+vx, y+vy)
for (i=0; i<next_step; i++)
{
    collision_tile(x, y)
    x += sign(vx)
    y += sign(vy)
}
I have this as my collision code using tiles as masks
Code:
/// @desc collision_tile()
/// @arg x
/// @arg y

var _x = argument[0]
var _y = argument[1]

var lay_id   = layer_get_id("Collision_0")
var map_id   = layer_tilemap_get_id(lay_id)
var tile     = tilemap_get(map_id, _x >> 4, _y >> 4)

//switch (tile)
//{
    collision_perform_t(bbox_left, bbox_bottom-16) collision_perform_t(bbox_right, bbox_bottom-16)
//}
Code:
/// @desc collision_perform_t(x, y)

var _x = next_mul(argument[0], 16) / 16
var _y = next_mul(argument[1], 16) / 16

var lay_id   = layer_get_id("Collision_0")
var map_id   = layer_tilemap_get_id(lay_id)
var tile     = tilemap_get(map_id, _x, _y)

show_debug_message(tile)
if (tile == 1) // top platform
{
    while(!tile == 1)
    {
        y += sign(vy)
        tile     = tilemap_get_at_pixel(map_id, _x, _y)
    }
    vy = 0
}
Code:
/// @desc next_mul(value, mulitpule)

return ceil(argument[0] / argument[1]) * argument[1]
Code:
/// @desc prev_mul(value, mulitpule)

return floor(argument[0] / argument[1]) * argument[1]
 

TheouAegis

Member
if moving right, check if there is no tile at bbox_left+tile width. If moving left, check if there is no tile at bbox_right-tile width.

and if you are working with tiles, you do not need to do a loop like that at all. All you need to do is snap yourself to the next grid row or column.
 
S

Shadowblitz16

Guest
I got it by doing..

Code:
/// @desc collision_tile()
/// @arg x
/// @arg y

var _x = argument[0]
var _y = argument[1]

collision_perform_t(bbox_left, bbox_bottom+1) collision_perform_t(bbox_right, bbox_bottom+1)
Code:
/// @desc collision_perform_t(x, y)

var _x = argument[0]
var _y = argument[1]
var _tile_x = _x >> 4
var _tile_y = _y >> 4

var lay_id   = layer_get_id("Collision_0")
var map_id   = layer_tilemap_get_id(lay_id)
var tile     = tilemap_get(map_id, _tile_x, _tile_y)


if (tile == 1 and _y mod 16 == 0) { show_debug_message(tile); if (vy > 0) { vy = 0; }}
I need to loop because I need to check collision every pixel
 
Top