I've been trying for a couple of days to solve an issue I'm having with top-down 2D collisions, whenever I collide with tiles that have adjacent collidable tiles my player sticks to the wall, If I collide right or left I can't move up or down, the same for the Y axis, I can't move left or right when colliding from the top or bottom. Here's a picture to represent my issue a bit better:
The gray boxes represent the collision area.
Here is my code:
Rectangle tileRect = new Rectangle((int)tile.Position.X, (int)tile.Position.Y, tile.SourceRect.Width, tile.SourceRect.Height);
Vector2 temporaryPlayerPosition = player.Sprite.Position - player.Velocity;
if (player.CollisionBox.Intersects(tileRect))
{
if ((player.CollisionBox.Right >= tileRect.Left && player.CollisionBox.Right < tileRect.Right) ||
(player.CollisionBox.Left <= tileRect.Right && player.CollisionBox.Right > tileRect.Left))
{
player.CollisionBox.X = (int)temporaryPlayerPosition.X;
player.Sprite.Position.X = temporaryPlayerPosition.X;
}
if ((player.CollisionBox.Bottom >= tileRect.Top && player.CollisionBox.Bottom < tileRect.Bottom) ||
(player.CollisionBox.Top <= tileRect.Bottom && player.CollisionBox.Top > tileRect.Top))
{
player.CollisionBox.Y = (int)temporaryPlayerPosition.Y;
player.Sprite.Position.Y = temporaryPlayerPosition.Y;
}
}
If anyone could point me to the right direction I would be grateful!! Thanks again!
EDIT!!!
I changed my whole collision code so it does a forward check before handling the displacemente of the sprite, I still have the stickyness issue though. This is the new code:
Rectangle forwardCollision = new Rectangle((int)(player.CurrentPos.X + (player.Velocity.X*4)), (int)(player.CurrentPos.Y + (player.Velocity.Y*4)), player.Sprite.SourceRect.Width, player.Sprite.SourceRect.Height);
player.CanRunX = player.CanRunY = true;
foreach (TmxTile tile in tileList)
{
tile.Update(gameTime);
Rectangle tileRect = new Rectangle((int)tile.Position.X, (int)tile.Position.Y, tile.SourceRect.Width, tile.SourceRect.Height);
if (forwardCollision.Intersects(tileRect) && SolidTileIds.Contains(tile.Id))
{
if (player.Velocity.X != 0)
player.CanRunX = false;
if (player.Velocity.Y != 0)
player.CanRunY = false;
}
}
foreach(DebugRectangle rectangle in rectangleList)
{
rectangle.Update(gameTime);
}
if (player.CanRunX)
player.Sprite.Position.X += player.Velocity.X;
else
player.Sprite.Position.X -= player.Velocity.X;
if (player.CanRunY)
player.Sprite.Position.Y += player.Velocity.Y;
else
player.Sprite.Position.Y -= player.Velocity.Y;
player.CurrentPos = player.Sprite.Position;
player.CollisionBox.X = (int)player.Sprite.Position.X;
player.CollisionBox.Y = (int)player.Sprite.Position.Y;
player.DebugRectangle.Position.X = forwardCollision.X;
player.DebugRectangle.Position.Y = forwardCollision.Y;