Jump to content
  • Advertisement
Sign in to follow this  
BlackDragon777

Player Position vs Map's Tile position

This topic is 4786 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

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 already
tile_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 it
player_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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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
the offset by passing the address to your offset variable


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

Share this post


Link to post
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;

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!