I'm having a few problems with collision detection in my game (written in C# with SDL.Net). Detecting the floor and roof is fine, as does detecting sides of tiles when not jumping/falling. My problem comes when the player jumps and hits one of the sides of a tile.
Sometimes the player (blue) enters the tile, like this: https://i.sstatic.net/SSjtR.png At first I thought this was because it was checking for a collision then moving the player then drawing, but changing it has no effect.
Other times it will randomly move from the overlapping position above to here: https://i.sstatic.net/0esSw.png
public void PlayerCollision2 (ref Player player)
{
Rectangle rectLeft = new Rectangle (new Point ((int)player.x, (int)player.y), new Size (1, Player.HEIGHT));
Rectangle rectRight = new Rectangle (new Point ((int)(player.x + Player.WIDTH), (int)player.y), new Size (1, Player.HEIGHT));
Rectangle rectTop = new Rectangle (new Point ((int)player.x, (int)player.y), new Size (Player.WIDTH, 1));
Rectangle rectBot = new Rectangle (new Point ((int)player.x, (int)(player.y + Player.HEIGHT + 1)), new Size (Player.WIDTH, 1));
List<TileDirectionRelPlayer > lst = new List<TileDirectionRelPlayer> ();
foreach (List<Tile> r in map) {
foreach (Tile c in r) {
if (c.tileType == TileType.Air)
continue;
TileDirectionRelPlayer t = new TileDirectionRelPlayer ();
t.tile = c;
if (c.rect.IntersectsWith (rectBot)) {
t.below = true;
lst.Add (t);
} if (c.rect.IntersectsWith (rectTop)) {
t.above = true;
lst.Add (t);
} if (c.rect.IntersectsWith (rectLeft)) {
t.left = true;
lst.Add (t);
} if (c.rect.IntersectsWith (rectRight)) {
t.right = true;
lst.Add (t);
}
}
}
if (lst.Count == 0 && !player.jumping) {
player.falling = true;
} else {
foreach (TileDirectionRelPlayer t in lst) {
MovePlayer (ref player, t, new Rectangle[] {rectLeft, rectRight, rectTop, rectBot});
}
}
}
private void MovePlayer (ref Player player, TileDirectionRelPlayer tile, Rectangle[] rectangles)
{
if (tile.above && rectangles[2].IntersectsWith(new Rectangle(new Point((int)tile.tile.x,(int)tile.tile.y+Tile.HEIGHT), new Size(Tile.WIDTH,7)))) {
player.falling = true;
player.jumping = false;
player.ySpeed = 0;
player.y = tile.tile.y + Tile.HEIGHT + 1;
}
if (tile.left && tile.tile.y < player.y) {
player.x = tile.tile.x + Tile.WIDTH;
}
if (tile.below && !player.jumping && rectangles[3].IntersectsWith(new Rectangle(new Point((int)tile.tile.x,(int)tile.tile.y), new Size(Tile.WIDTH,7)))) {
player.y = tile.tile.y - Player.HEIGHT - 1;
player.falling = false;
player.ySpeed = 0;
}
if (tile.right && tile.tile.y < player.y) {
player.x = tile.tile.x - Player.WIDTH - 1;
}
}
I have no idea why this is happening or how to fix it, can someone point me in the right direction please?
EDIT: There is a video here if it helps