Jump to content
  • Advertisement
Sign in to follow this  
MoonChild1607

Perfect collision in a tile based platform game?

This topic is 3411 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on a little tile based platform game in c++ but I'm having some problems with the collision. All the tiles and the player are 16 pixels width and 16 pixels high. This is a function that I call upon for checking the collision.
//Handle the collision of the maps
int Handle_mapcollision(int x, int y) {
    //Variables
    int ofs, tile, tilex, tiley;
    
    //Tiles divided by object's x and y position
    tilex=x/16;
    tiley=y/16;
    
    //Tile counter is * width
    ofs=(tiley*20)+tilex;
    
    //Checks what the current map is
    if (currentmap==0) {
       tile=leveltestcol[ofs];
    }
    return tile;
}
and I use this for the player
//Handle input
void Handle_player() {
     //================VARIABLES====================
     //Initialize keys
     int key,keytrig,keyl,keyu,keyr,keyd;
     int tile_left,tile_up,tile_right,tile_down;
     
     //===================KEYS===================
     //Initialize keys
     CML_GetKeys(&key,&keytrig);
     
     //Binds they keys to variables
     keyl=CML_INPUT_KEY_LEFT;
     keyu=CML_INPUT_KEY_UP;
     keyr=CML_INPUT_KEY_RIGHT;
     keyd=CML_INPUT_KEY_DOWN;
     
     //=============COLLISION==============
     //Check for collision
     tile_left=Handle_mapcollision(int(player.x-1),int(player.y+8));
     tile_up=Handle_mapcollision(int(player.x+8),int(player.y-1));
     tile_right=Handle_mapcollision(int(player.x+17),int(player.y+8));
     tile_down=Handle_mapcollision(int(player.x+8),int(player.y+17));     
     
     //Checks for a solid tile beneath the player
     if (tile_down==1) {
        //Stop falling
        player.gravity=0;
        
        //Reset jumping
        player.jumping=false;
        
        //Set the player on the right spot, stops it from clipping slightly in solid tiles
        player.y=floor(player.y/16)*16;
        //floor((player.y+1)/16)*16;
     }
     
     //==================INPUT=========================
     //Checks if the left key is pressed
     if (key & keyl) {
        //Checks for non solid tile
        if (tile_left!=1) {
           //Move the player
           player.x-=player.speed;
        }
        //Sets the direction
        player.direction=0;
     }

     //Checks if the right key is pressed
     if (key & keyr) {
        //Checks for non solid tile
        if (tile_right!=1) {
           //Move the player
           player.x+=player.speed;
        }
        //Sets the direction
        player.direction=2;
     }
     
     //Checks if the up key is pressed
     if ((key & keyu) && (player.jumping==false)) {
        //Checks for non solid tile
        if (tile_up!=1) {
           //Let the player jump
           player.gravity=-6;
           player.jumping=true;
       }
     }
     //===================GRAVITY======================
     //Sets gravity
     player.y+=player.gravity;
     if (tile_down!=1) {
        player.gravity+=0.6f;
        if (player.gravity>7)player.gravity=7;
     }

}
The result of this is that it kinda works, but not really well! You can download a compiled version of all the code here http://www.mediafire.com/?ynjn2ctknmw You can jump through some blocks sometimes, get stuck and so on. You'll notice it quick enough by just jumping around. Image Hosted by ImageShack.us [Edited by - MoonChild1607 on May 18, 2009 3:29:11 AM]

Share this post


Link to post
Share on other sites
Advertisement
I'd take a good hard look at these four lines:

tile_left=Handle_mapcollision(int(player.x-1),int(player.y+8));
tile_up=Handle_mapcollision(int(player.x+8),int(player.y-1));
tile_right=Handle_mapcollision(int(player.x+17),int(player.y+8));
tile_down=Handle_mapcollision(int(player.x+8),int(player.y+17));

First, you're going "left" and "right" by modifying the y value, which I find counterintuitive. But second, while it's true that every object can only overlap at most four tiles at a time, I don't think this setup will check the four tiles you need to check. At the moment, my brain isn't quite up to describing what you need to do here, so I suggest drawing out a diagram with your player and some blocks, noting down X and Y values, and then figuring out which blocks you'll actually be checking for collision with.

Share this post


Link to post
Share on other sites
Ah, my mistake. I thought you were doing rect-rect detection, but your Handle_mapcollision function is only looking at one point. Shows what I get for trying to debug unfamiliar code while I have a migraine.

Slide your red box over to the right a bit (in your second diagram) and I think you'll see the problem. Its upper-right corner will intersect a terrain block well before one of the lines notices it.

Share this post


Link to post
Share on other sites
I'm working on a similar platform game at present, and the way I do the map collision (which works fine) is to check horizontal and vertical collision separately. I pass a RECT structure containing the sprite's current position and a reference to the x or y displacement which will result if there is no collision.

COLLIDETYPE CheckHorzCollide(RECT& current_position, int& x_displacement);
COLLIDETYPE CheckVertCollide(RECT& current_position, int& y_displacement);

If there is a collision the x or y displacement is reduced to the amount which puts the sprite up against the tile or tiles. I'm checking against upper and lower tiles horizontally and left and right tiles vertically. I think this is better than checking x and y collisions together. You could return a bool value but I'm returning information about the collision that I can use such as whether the sprite collided with the top or bottom of the tile. Hope this helps.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!