# Player Position vs Map's Tile position

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

## Recommended Posts

Hey guys! Thanks for all your help along the way. However I have one more problem that I would like help with. I guess this is more of a math related issue. I am working on a 2d side scroller similar to Mario Brothers, Sonic, etc. My map in memory is setup like the following 0 = Sky area 1 = Ground 2 = Dirt 00000000 00000010 00010110 11111111 22222222 Now the idea is that the player shouldn't be able to walk through the ground area. He can jump on it but he can't walk through it. The way I approach this problem is I take the player's x and y value and convert it to a tile position. Each tile is 32x32. So I calculate the Player's map position like so, i_PlayerMapPosX = abs(double(Player.iX)/32); i_PlayerMapPosY = abs(double(Player.iY)/32); However since the map scrolls from left to right, I had to change this just a little. It not is calculated like the following, i_PlayerMapPosX = abs(double(Player.iX)/11); i_PlayerMapPosY = abs(double(Player.iY)/32); This is because the tiles are moving at the same time the player is moving because the map is scrolling. So in a loop, I do a collision test to see if the tile in front of the player has a collision value like so, if(MapTile[i_PlayerMapPosX+1][i_PlayerMapPosY].SpecialInfo[0]==1) { //Then Proess the Collision } This works fine if the player doesn't have to jump. However, if the player jumps, then the i_PlayerMapPosY changes slightly which makes the game think that the tile in front of the player is a sky tile if a sky tile is above a brick. A Visual representation works better than my description, so if you don't mind, I have a very small demo with my problem. http://www.geocities.com/blackdragon7373/scroll_test2.zip I have tried doing something like i_PlayerMapPosY = ceil(double(Player.iY)/32); when the down key was pressed and and changing it back to i_PlayerMapPosY = abs(double(Player.iY)/32); when the up key was pressed again but that is faulty logic and doesn't work correctly. So what kind of calculation or algorthym would you use to solve this problem? Thanks in advance! GOD Bless you Always!!!!!!

##### Share on other sites
I would suggest using bounding box collision between kirby and the blocks. I haven't studied the code too much since I tried the demo first but something looks a little funny (I will have another look later). As I mentioned, I would try performing a bounding box collision detection between kirby and the tile he wants to move to and that should help you out in the long run since you will probably want to do bounding box collisions between kirby and other sprites as well.

Hope it helps.

##### Share on other sites
I could do that however the problem is that the bricks are apart of them map so I need to know where the player is relative to the mpa at all times. Any other ideas? Thanks!

##### Share on other sites
there are a few possiblilty,
1. is to keep track of direction of character's movement, which is a bit silly... or
2. add a bias before you abs, dunno if that will work but most cases it works...
3. i am sure you can still use the bounding box. might need some changes to the logic.

or something like that (sorry, brain too drain for solving AI issues to think of correct anwser)

##### Share on other sites
No worries. Or maybe I could do if(Player.iX % 32 == 0) and then inc or dec the value of the player's i_PlayerMapPosX depending on what direction the player is going.

What do you think?

##### Share on other sites
Quote:
 I could do that however the problem is that the bricks are apart of them map so I need to know where the player is relative to the mpa at all times. Any other ideas? Thanks!

That is fine that the bricks are part of the map. You can easily define a rectangle for them by using the following:
// for clarity because I don't know if you are using DX,OpenGL, or SDL etc.// resembles an SDL_Rect structure for my own sanity.struct rect{    int x;    int y;    int w; // width    int h; // height}RECT;RECT tile_rect;RECT player_rect;// assuming you found the i_PlayerMapPosX + Y alreadytile_rect.x = i_PlayerMapPosX*TILE_WIDTH;tile_rect.y = i_PlayerMapPosY*TILE_HEIGHT;tile_rect.w = TILE_WIDTH;tile_rect.h = TILE_HEIGHT;// assuming your player has a position where the top left corner// is the origin. If there is an anchor point just offset the x+y// by the anchor values.player_rect.x = Player.iX;player_rect.y = Player.iY;player_rect.w = Player.iWidth; // hope it exists or something like itplayer_rect.h = Player.iHeight;

Then you just check if tile_rect and player_rect collide. pretty simple right?

Here is a link to a tilemap demo I did a while ago with very simple point in rectangle collision detection. I know it is different than a side scroller but the concepts are the same.

##### Share on other sites
Thanks I will take a look. I know how to do a collision detection check. My problem is that my player's x and y values are out of sync with its Map x and y values. I need to get them in sync. That's what I am asking here. Thanks!

##### Share on other sites
Not sure if this is what you want to synch the character and map
------------------
void Collision(float checkx, float checky, int checkdirection)
{

int cmapx;
int cmapy;

//divide the x figure by 1.5f to get the X tile
cmapx = checkx / 1.5f;
ninja.mapx = cmapx;

//divide the y figure by 1.5f to get the Y tile
cmapy = checky / 1.5f;
ninja.mapy = cmapy;

//sort direction so we can progress
cdirection = checkdirection;

//Grab the map index
checkmap = map[cmapx][cmapy].index;

called with
Collision(ninja.cx,ninja.cy,WALK_EAST);

good luck

##### Share on other sites
To get a position's tile index and tile offset
WU, the World Unit is your tile's square size
This function returns the tile index and you get

int TileIndexOffset(int pos, int *offset){   *offset = pos % WU;   return (pos - *offset) / WU;}

##### Share on other sites
Here is a snippet from a very very old code of mine, when I was just starting game programming. It basically does what you want to do, but I won't say anything about it's quality :p

		// Move the players		bool update_x = FALSE;	// we need these so we can perform both collision checks		bool update_y = FALSE;	// before changing any values		// check for colissions. If there is a colission, stop velocity		if ((!level.tiles[level.level[(static_cast <int> (P[playerCount].y + PLAYERSIZE))][(static_cast <int> (P[playerCount].x + PLAYERSIZE + P[playerCount].velX))]].solid)		 && (!level.tiles[level.level[(static_cast <int> (P[playerCount].y - PLAYERSIZE))][(static_cast <int> (P[playerCount].x + PLAYERSIZE + P[playerCount].velX))]].solid)		 && (!level.tiles[level.level[(static_cast <int> (P[playerCount].y + PLAYERSIZE))][(static_cast <int> (P[playerCount].x - PLAYERSIZE + P[playerCount].velX))]].solid)		 && (!level.tiles[level.level[(static_cast <int> (P[playerCount].y - PLAYERSIZE))][(static_cast <int> (P[playerCount].x - PLAYERSIZE + P[playerCount].velX))]].solid))			update_x = TRUE;		else			P[playerCount].velX = (-P[playerCount].velX / 2);		if ((!level.tiles[level.level[(static_cast <int> (P[playerCount].y + PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x + PLAYERSIZE))]].solid)		 && (!level.tiles[level.level[(static_cast <int> (P[playerCount].y - PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x + PLAYERSIZE))]].solid)		 && (!level.tiles[level.level[(static_cast <int> (P[playerCount].y + PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x - PLAYERSIZE))]].solid)		 && (!level.tiles[level.level[(static_cast <int> (P[playerCount].y - PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x - PLAYERSIZE))]].solid))			update_y = TRUE;		else			P[playerCount].velY = (-P[playerCount].velY / 2);		// check for possible minimal chance of player getting stuck		if (update_x && update_y)			if ((level.tiles[level.level[(static_cast <int> (P[playerCount].y + PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x + PLAYERSIZE + P[playerCount].velX))]].solid)			 || (level.tiles[level.level[(static_cast <int> (P[playerCount].y - PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x + PLAYERSIZE + P[playerCount].velX))]].solid)			 || (level.tiles[level.level[(static_cast <int> (P[playerCount].y + PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x - PLAYERSIZE + P[playerCount].velX))]].solid)			 || (level.tiles[level.level[(static_cast <int> (P[playerCount].y - PLAYERSIZE + P[playerCount].velY))][(static_cast <int> (P[playerCount].x - PLAYERSIZE + P[playerCount].velX))]].solid))			{P[playerCount].velX = (-P[playerCount].velX / 2); P[playerCount].velY = (-P[playerCount].velY / 2);}		// move if possible		if (update_x)			P[playerCount].x += P[playerCount].velX;		if (update_y)			P[playerCount].y += P[playerCount].velY;

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 14
• 46
• 22
• 27
• ### Forum Statistics

• Total Topics
634047
• Total Posts
3015226
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!