I am trying to create a pacman game to learn XNA, but I am having some problems to get the collision detection working. The game is tile based, where 1 is a wall and 0 is walkable. It then takes the tile you are standing on plus the 4 around it, and if it collides with one of them and the tile value is not 0 will it reset the position to what it was before the move. For some reason however it just doesn't work, it gets randomly stuck and sometimes I can even move though walls.
Here is my collision detection:
var oldPos = Position;
// Updates the Position
base.Update(theGameTime, mSpeed, mDirection);
// Test Collidetion
Rectangle objRect = new Rectangle((int)Position.X, (int)Position.Y, 32, 32);
bool isCollided = false;
Vector2 curTitle = GetCurrentTitle();
// Test UP, DOWN, LEFT, RIGHT
int tile;
Rectangle testRect;
if ((int)curTitle.Y < 0 || (int)curTitle.X < 0 || (int)curTitle.Y >= map.MapSizeWidth - 1 || (int)curTitle.X >= map.MapSizeHeight - 1)
isCollided = true;
if (!isCollided)
{
tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X];
testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize);
if (tile != 0 && rectangle_collision(testRect, objRect))
isCollided = true;
if (curTitle.Y != 0)
{
tile = map.Tiles[(int)curTitle.Y - 1, (int)curTitle.X];
testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y - 1) * map.TileSize, map.TileSize, map.TileSize);
if (tile != 0 && rectangle_collision(testRect, objRect))
isCollided = true;
}
tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X];
testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y - 1) * map.TileSize, map.TileSize, map.TileSize);
if (tile != 0 && rectangle_collision(testRect, objRect))
isCollided = true;
if (curTitle.X != 0)
{
tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X - 1];
testRect = new Rectangle(((int)curTitle.X - 1) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize);
if (tile != 0 && rectangle_collision(testRect, objRect))
isCollided = true;
}
tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X + 1];
testRect = new Rectangle(((int)curTitle.X + 1) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize);
if (tile != 0 && rectangle_collision(testRect, objRect))
isCollided = true;
}
if (isCollided)
Position = oldPos;
Can any one see why my collision detection is not working?
EDIT: I have uploaded the whole project to http://sogaard.us/Pacman.zip
I'm not sure if this is causing the full problem. But on your third tile check (where you check the tile below) you are checking the tile above again.
This part here:
tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X];
On the next line you still have this inside the params for the testRect:
((int)curTitle.Y - 1) * map.TileSize
Should be:
((int)curTitle.Y + 1) * map.TileSize
Full corrected snippet:
tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X];
testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y + 1) * map.TileSize, map.TileSize, map.TileSize);
if (tile != 0 && rectangle_collision(testRect, objRect))
isCollided = true;
Hope this helped :)