2d tilemap collision

Anything related in any way to game development as a whole is welcome here. Tell us about your game, grace us with your project, show us your new YouTube video, etc.

Moderator: PC Supremacists

Post Reply
jjackdev
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 16
Joined: Mon Aug 30, 2010 11:55 pm

2d tilemap collision

Post 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.
Last edited by jjackdev on Thu Sep 02, 2010 1:18 pm, edited 2 times in total.
User avatar
EdBoon
Chaos Rift Junior
Chaos Rift Junior
Posts: 258
Joined: Fri May 28, 2010 10:44 pm
Current Project: Top down multiplayer shooter using unity 3D
Favorite Gaming Platforms: 360, SNES, ps1
Programming Language of Choice: C++, C#
Location: Atlanta, GA
Contact:

Re: 2d tilemap collision

Post 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 ;)
Undead Empire -> http://bit.ly/dYdu3z
Gamerscore Tracker -> http://bit.ly/vI4T4X
Undead Empire: Hellfire -> http://bit.ly/1AgC4ZY
facebook.com/BigRookGames twitter.com/BigRookGames
youtube.com/user/bigrookdigital
jjackdev
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 16
Joined: Mon Aug 30, 2010 11:55 pm

Re: 2d tilemap collision

Post 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.
krilik
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 25
Joined: Sat Apr 18, 2009 11:24 pm
Favorite Gaming Platforms: SNES,PS1

Re: 2d tilemap collision

Post 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?
jjackdev
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 16
Joined: Mon Aug 30, 2010 11:55 pm

Re: 2d tilemap collision

Post 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.
Post Reply