Page 1 of 1

2d tilemap collision

Posted: Wed Sep 01, 2010 10:56 pm
by jjackdev
Ok so I have been trying to create a way to have solid tiles in my game. Here is some of the code for the collision that I am using.

Code: Select all

bool IsCollision(SDL_Rect r1, SDL_Rect r2 )
{
    if (    r1.x            <       r2.x+r2.w &&
		r1.x+r1.w    >       r2.x &&
		r1.y            <       r2.y+r2.h &&
		r1.y+r1.h     >       r2.y )
    {
        return true;
    }
    return false;
}

int collision() {
	SDL_Rect playerRect, tile[8];
	playerRect = player.getPlayerRect();
	
	bool solid[8];
	
	tile[0].x = playerRect.x;
	tile[0].y = playerRect.y/2;
	tile[0].w = 32;
	tile[0].h = 32;
	
	tile[1].x = (playerRect.x) + 32;
	tile[1].y = playerRect.y;
	tile[1].w = 32;
	tile[1].h = 32;
	
	tile[2].x = (playerRect.x) + 32;
	tile[2].y = (playerRect.y) - 32;
	tile[2].w = 32;
	tile[2].h = 32;
	
	tile[3].x = playerRect.x;
	tile[3].y = (playerRect.y)-32;
	tile[3].w = 32;
	tile[3].h = 32;
	
	tile[4].x = (playerRect.x) - 32;
	tile[4].y = (playerRect.y) + 32;
	tile[4].w = 32;
	tile[4].h = 32;
	
	tile[5].x = (playerRect.x) - 32;
	tile[5].y = (playerRect.y);
	tile[5].w = 32;
	tile[5].h = 32;
	
	tile[6].x = (playerRect.x) - 32;
	tile[6].y = (playerRect.y) + 32;
	tile[6].w = 32;
	tile[6].h = 32;
	
	tile[7].x = (playerRect.x);
	tile[7].y = (playerRect.y) + 32;
	tile[7].w = 32;
	tile[7].h = 32;
	
	tile[8].x = (playerRect.x) + 32;
	tile[8].y = (playerRect.y) + 32;
	tile[8].w = 32;
	tile[8].h = 32;
	
	for (int i = 0; i < 8; i++) {
		solid[i] = cMap[tile[i].y][tile[i].x];
	}
	
	for (int i = 0; i < 8; i++) {
		if (solid[i] == true && IsCollision(playerRect, tile[i]) == true) {
			printf("Collision!\n");
			return 1;
		}
	}
	return 0;
}
It looks long but it is just assignment of variables. But the problem with it is that I registers a collision everywhere except when the player is moved to the very top of the screen and with the cameraY at 0. The character is 40 pixels and I have no idea how to fix this. Please help. Thank you.

Re: 2d tilemap collision

Posted: Thu Sep 02, 2010 8:13 am
by EdBoon
ran through the code real quick, do you have the map matrix for solid tiles you can post? One problem could be they are all solid, (i know how obvious that seems but you never know), the collision part seems okay. Also you are checking a 3x3 grid of tiles (9 total) but you set up SDL_Rect tiles[8] (8 total).

also, I'm assuming playerrect.x and y are its coordinate positions, tile0 checks for y/2. Did you mean to put this? if you were at 800,800 it would check the tile at 800, 400.

try setting the entire map to non-solid blocks and see if it still prints collision


EDIT* also if someone could move this to programming discussion it might help a bit for responses, just keep that in mind for your next programming posts, then you might get responses from people who actually know what they are talking about ;)

Re: 2d tilemap collision

Posted: Thu Sep 02, 2010 1:20 pm
by jjackdev
Alright thanks for the help here is the code for the matrix

Code: Select all

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
I know it looks like a mario level it was just a test. And it is initialized as

Code: Select all

map[Y_MAX_TILES][X_MAX_TILES] = {};
Thanks for the help.

Re: 2d tilemap collision

Posted: Thu Sep 02, 2010 10:53 pm
by krilik
I'm pretty sure this is your problem.

Code: Select all

solid[i] = cMap[tile[i].y][tile[i].x];
You're indexing the wrong values here.

The values of those indexes are going to be 0s (or where ever your player location is) and (player location +)32s because you assigned the x and y values of your tiles like this

Code: Select all

tile[1].x = (playerRect.x) + 32;
   tile[1].y = playerRect.y;
You should be indexing the values something like this to read from your matrix

Edited: Forgot the other for loop to loop through the solid array

Code: Select all

for (int i = 0; i < 9; i++)
{
     for (int x = 0; x < 3; x++)  //technically this should loop until X_MAX_TILES
     {
          for (int y = 0; y < 3; y++) //loop until Y_MAX_TILES
          {
               //I don't know why you have it reversed y,x but I'm keeping it the same as you declared in your Map matrix
                solid[i] = cMap[y][x]; 
          }
     }
}
Honestly, I don't understand why you even have another array called solid to hold that data. It should already be defined in your map array.

And you should set the values of your tile's x and y coordinates by multiplying the Map array index by 32. Something like this:

Code: Select all

for (int i = 0; i < 9; i++)
{
     for (int x = 0; x < X_MAX_TILES; x++)
     {
          for (int y = 0; y < Y_MAX_TILES; y++)
          {
               tile[i].x = x * 32;
               tile[i].y = y * 32;
          }
     }
}
I'm winging all of this without testing it BTW. Its just how I would do it. But I'm not an expert in C++ so maybe I'm not understanding your reasoning behind doing it the way you are doing it. Maybe someone who knows C++ better than me can comment on it?

Re: 2d tilemap collision

Posted: Thu Sep 02, 2010 11:31 pm
by jjackdev
Thanks for all of the help but I figured that I could just use some static Rects and test a collision with them with the player rect.