I'm having a glitch with this simple collision algorithm. I'm doing the rpg game tutorial from codingmadeeasy, and the collision is much alike any algorithm collision I've done in previous platformer style games. I've had this problem with previous games as well, just don't remember the fix. I have a map, it has lots of tiles, some are flagged as solid. their Update method checks for collision with the player. If the tile is solid, it should stop the player and move him to a valid location.
Problem is when I go up or down, stick to the tile, and press a left or right movement key.
For example:
I'm pressing the Down key, I'm on top of the solid tile, and I press to go Left. at that moment, the player is relocated to to the Right of the tile.
This wouldn't happen if I go left or right and press up or down because of the if
order in the collision method.
public void Update(GameTime gameTime, ref Player player)
{
if (State != TileState.Solid) return;
Rectangle tileRect =
new Rectangle((int)Position.X, (int)Position.Y,
SourceRect.Width, SourceRect.Height);
Rectangle playerRect =
new Rectangle((int)player.Sprite.position.X, (int)player.Sprite.position.Y,
player.Sprite.SourceRect.Width, player.Sprite.SourceRect.Height);
HandleCollisionWithTile(player, playerRect, tileRect);
}
/// <summary>
/// Repositions the player at the current position after collision with tile
/// </summary>
/// <param name="player">the player intersecting with the tile</param>
/// <param name="playerRect">the rectangle of the player</param>
/// <param name="tileRect">the rectangle of the tile</param>
private static void HandleCollisionWithTile(Player player, Rectangle playerRect, Rectangle tileRect)
{
// Make sure there's even collosion
if (!playerRect.Intersects(tileRect)) return;
// Left
if (player.Velocity.X < 0)
player.Sprite.position.X = tileRect.Right;
// Right
else if (player.Velocity.X > 0)
player.Sprite.position.X = tileRect.Left - player.Sprite.SourceRect.Width;
// Up
else if (player.Velocity.Y < 0)
player.Sprite.position.Y = tileRect.Bottom;
// Down
else if (player.Velocity.Y > 0)
player.Sprite.position.Y = tileRect.Top - player.Sprite.SourceRect.Height;
// Reset velocity
player.Velocity = Vector2.Zero;
}
Obviously, If I switch the two first ifs with the last, that would happen if I come from the side and press up or down.
What exactly am I missing?