# Perfect collision in a tile based platform game?

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

## 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. [Edited by - MoonChild1607 on May 18, 2009 3:29:11 AM]

##### Share on other sites
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 on other sites
Those 4 lines check the points of the player as marked with magnenta colored lines in the picture below.

##### 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 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.

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633660
• Total Posts
3013222
×