# Tile map collision is not working properly

I am having problems setting collision between my sprite and the tiles. I have only done the code for colision for moving upwards but some places on the map it moves up and some places it doesn't.

Here is what I have so far:

Vector2 position;
private static float scalingFactor = 32;

static int tileWidth = 32;
static int tileHeight = 32;

int[ , ] map = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, },
{0, 0, 0, 0, 0, 0, 0, 1, 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, 1, 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, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
};


// This is in turtle.update

if ( keyboardState.IsKeyDown( Keys.Up ) )
{
if ( position.Y > screenHeight / 4 )
{
//// current position of the turtle on the tiles
int mapX = ( int )( position.X / scalingFactor );
int mapY = ( int )( position.Y / scalingFactor ) - 1;

if ( isMovable( mapX , mapY , map ) )
{
position.Y = position.Y - scalingFactor;
}
}
else
{
MoveUp();
}
}

private void MoveUp()
{
motion.Y = -1;
}

public bool isMovable( int mapX , int mapY , int[ , ] map )
{
if ( mapX < 0 || mapX > 19 || mapY < 0 || mapY > 20 )
{
return false;
}
int tile = map[ mapX , mapY ];
if ( tile == 0 )
{
return false;
}

return true;
}

protected override void Update( GameTime gameTime )
{
turtle.Update( screenHeight , scalingFactor , map );
base.Update( gameTime );
}


EDIT: What i have tried to do is get the postion of my sprite and over which tile it is, then check whether the next tile is a path or a wall.

• It's unclear what the problem is. Some places it works and others it doesn't? What does that mean? Also, what is position.Y > screenHeight / 4 and what is MoveUp() doing? Lastly, questions that are basically just "Here's my code, find my problem" are not good questions, you need to tell us what you've tried and help us help you. – MichaelHouse May 30 '12 at 14:31
• the problem i am having is that it is detecting that tiles on my map where it is supposed to be 0(sprite not allowed to move on tile with 0 value), its detecting it as 1, which is allowing the sprite to move where it shouldn't be able to. Also some places on the map where it is supposed to be 1(Sprite allowed to move) it doesnt. moveup() just moves the sprite up a pixel. position.Y is the position of the sprite. This is my first game, so sorry for not explaining properly as im still trying to understand and grasp most of the stuff myself. – Sigh-AniDe May 30 '12 at 17:43

No problem with being new to game development. You just need to make sure to provide enough information so that we can properly help you. Your on the right track with your code and it looks like your isMoveable() function is sound. I'm not sure what the difference between motion.Y and position.y are and why you're setting one vs the other depending on position.Y > screenHeight / 4, so the following maybe isn't what you want to achieve. However, I would suggest this simple structure for moving your character around.

// current position of the turtle on the tiles
int mapX = (int)(position.X / scalingFactor);
int mapY = (int)(position.Y / scalingFactor);
if (keyboardState.IsKeyDown(Keys.Up))
{
if (isMovable(mapX, mapY-1, map))
{
position.Y = position.Y - scalingFactor;
}
} else if (keyboardState.IsKeyDown(Keys.Down))
{
if (isMovable(mapX, mapY+1, map))
{
position.Y = position.Y + scalingFactor;
}
} else if (keyboardState.IsKeyDown(Keys.Right))
{
if (isMovable(mapX+1, mapY, map))
{
position.X = position.X + scalingFactor;
}
} else if (keyboardState.IsKeyDown(Keys.Left))
{
if (isMovable(mapX-1, mapY, map))
{
position.X = position.X - scalingFactor;
}
}


EDIT

This could be because of the way you're indexing into the map. Note orientation for your map as defined in code is not the way it will display on screen. You're indexing into it like this:

int tile = map[ mapX , mapY ];


So mapX is referencing the rows of your array and mapY is referencing the columns. So the top row of tiles on your screen from left to right are referencing the last column in your array from top to bottom.

• it still isnt working after changing the code to the way you did it, is there any way i can send you my project solution so you can see exactly whats the game actually doing? – Sigh-AniDe May 30 '12 at 18:12
• Nope sorry. You should absolutely learn to use the debugger and step through your code. Here's a little article I wrote about it. – MichaelHouse May 30 '12 at 18:17
• I did debug thorugh the application and thats how i know that the tiles that supposedly a 0 is returning a 1 and vice versa, but i dont know whats causing it. – Sigh-AniDe May 30 '12 at 18:20
• Is there a better way to go about adding collision to a tile map? If there is could you please point me to the right direction. Ive googled a lot as well and there isnt really any tutorials or explanations on how to do it. – Sigh-AniDe May 30 '12 at 18:36
• You should debug tileX and tileY. This should give good indication why the values being read are not as expected. For example, 0,0 could well be bottom of screen and so Y is upside down if that the case. – John May 30 '12 at 18:41

This looks suspect as I presume tile zero indicate movable and yet you return false

if ( tile == 0 )
{
return false;
}

• no that doesnt work, if i do that the sprite doesnt move up no matter what. – Sigh-AniDe May 30 '12 at 18:15
• tile zero indicates not movable, a wall. – Sigh-AniDe May 30 '12 at 18:17
• OK, probably rounding errors. You should do floor(.....) – John May 30 '12 at 18:17
• sorry, but what do you mean i should do floor? should i rather check if it is a movable tile? – Sigh-AniDe May 30 '12 at 18:21
• ok, typecasting to int does what floor does so ignore my previous comment – John May 30 '12 at 18:31