• 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!

Trying to convert my object-based pixel-perfect collision system to tile-based

Hey guys,

So I've found quite a few tutorials on how to do pixel-perfect collisions with tiles but they're simply too advanced for me to follow along. I'm trying to learn so I care more about understanding everything I'm coding than about the code being as efficient as it can be for now.

I've made single-pixel thin collision tiles which I'm using to draw over my level because I'm going for Castlevania-style platforms and stairs so I only want the collision to be in place if the character's bounding box is touching the edge of the sprite. I'm now trying to convert my old object-based pixel-perfect collision code to work with these collision tiles.

I've gotten to the point where I would have checked if there was an object with the collision parent at the place I'm about to move to and if so check the next pixel up and so forth until I've reached the predetermined height limit for walking and I'm not sure how to do the equivalent with tiles.

Can you please point me in the right direction, keeping in mind that I'm still very much a noob and so that I may need more explaining that more experienced users would?

GML:
var bbox_side;

if(player_hMovement > 0)
    {bbox_side = bbox_right;
    else bbox_side = bbox_left;
    }
    
if(tilemap_get_at_pixel(tileMapID, bbox_side+player_hMovement, bbox_top) !=0 or {tilemap_get_at_pixel(tileMapID, bbox_side+player_hMovement, bbox_bottom) !=0)
    
    walkingHeight = 0;
    
    while (place_meeting(x-player_hMovement, y-walkingHeight, obj_meta_colliderParent) && walkingHeight <= maxWalkingHeight) walkingHeight +=1;
    
    if place_meeting(x-player_hMovement, y-walkingHeight, obj_meta_colliderParent){
        while(!place_meeting(x-sign(player_hMovement), y, obj_meta_colliderParent)){
                x -= sign(player_hMovement);
        }
        player_hMovement = 0;
    }
    else{
        y-=    walkingHeight;
    }
}
else{

    walkingHeight = 0;
    
    while (player_vMovement > 0 && !place_meeting(x-player_hMovement, y+walkingHeight, obj_meta_colliderParent) && walkingHeight <= maxWalkingHeight) walkingHeight +=1;
    
    if(place_meeting(x-player_hMovement, y+walkingHeight, obj_meta_colliderParent)){
    y+= walkingHeight;
    }

}
 
which Castlevania are you referring to? There are, like, 5 or 6 styles.
Essentially I just meant one-way platforms and stairs with no collision until you get on them, both of which you can jump down from. However, making those isn't my main concern atm. I'm just trying to make basic collisions work by detecting if there is a tile where I'm trying to move to, and if so checking if there is a something one pixel in that direction, repeating until mI find a something and then moving the player object flush against it. It worked well with objects, but with tiles so far I only know how to check if there is a tile there. In the code above, it's when I get to the while loop that I don't know what to do for tiles.
 

TheouAegis

Member
You don"t need a while loop for tiles because they are aligned to a grid, unlike objects. Basically, you pick a point relative to the instance and check if there is a tile there. If so, calculate where you want that point to end up by flooring its coordinates (add your grid size to the result if moving left or up), then adjust the instance's coordinates accordingly. Your tiles should be full width, not 1 pixel. You just have to remember the one-way platform rules: positive vertical speed, collision below feet, no collision 1 tile height above that.

(Too busy to write a mock-up right now.)

Stairs vary between games. Classic stairs are just a single object with a direction specified. If the player is within 1 tile width from a stair object and the correct key (up/down) is held, the player faces that stair object, walks toward it, then changes to a stair-climbing state. The player changes back to a walking state when there is a ground tile under his feet (bbox_bottom+1) but not at his feet. Stairs don't actually exist in the classic series, which is why you can't jump onto them, although jumping while on a stair is simple enough to implement.

I'm not sure about Igavanias and Supervanias, but I would assume it would do a stair tile check, then check if a stair tile is in front of the player to determine if climbing up or down, then switching to the proper state.
 
Last edited:
@TheouAegis Ok, so with the information I've gathered I've written the following. Am I going in the right direction?

GML:
var bbox_side;

if(player_hMovement > 0){
        bbox_side = bbox_right;
    }
    else{
        bbox_side = bbox_left;
    }
   
if(tilemap_get_at_pixel(tileMapID, bbox_side+player_hMovement, bbox_top) !=0 or tilemap_get_at_pixel(tileMapID, bbox_side+player_hMovement, bbox_bottom) !=0){
    if(player_hMovement > 0){
        player_hMovement = 0;
        moveDistance = 1;
    }
    else if(player_hMovement < 0){
        moveDistance = -1;
        player_hMovement = 0;
    }
}
else{
    player_hMovement = 0;
    }
I really want to learn but this is very much at the edge of what I can kinda guess-code ATM. I'd love for someone who really understands all of this to basically give me a short course on how to handle these collisions and stairs mechanics so I can build on that understanding for the rest of my code. I know that's quite a bit to ask but maybe I can give you a few bucks in exchange for hopping on a voice chat with shared screens with me?
 
Last edited:
Top