# Why is my collision code blocking the player's movement in XNA?

Game Development Asked by Zawada on December 3, 2020

I have the following code to check for collisions in my game, but this code doesn’t work it as should. For example:

• I go from up to down and if collision is detect I can’t turn right;

• if I go from right to left and collision is detect I can’t turn down.

What is wrong with this code and how could I improve it?

foreach (var o in ObjectList) {
previousPosition = player.Position;
if (player.CollisionRectangle.Intersects(o.Rectangle) && o.isCollision == true) {
if (o.ObjectUpdateLeftRight(player, o.Position) == 0) player.CanRight = false;
if (o.ObjectUpdateLeftRight(player, o.Position) == 1) player.CanLeft = false;
if (o.ObjectUpdateUpDown(player, o.Position) == 2) player.CanUp = false;
if (o.ObjectUpdateUpDown(player, o.Position) == 3) player.CanDown = false;
}
}


and ObjectUpdateLeftRight and UpDown:

public int ObjectUpdateLeftRight(Player.Player player, Vector2 objectToCheck) {
if (player.Position.X < objectToCheck.X) return 0; // right
if (player.Position.X >= objectToCheck.X) return 1; // left
return -1;
}

public int ObjectUpdateUpDown(Player.Player player, Vector2 objectToCheck) {
if (player.Position.Y >= objectToCheck.Y) return 2; // up
if (player.Position.Y < objectToCheck.Y) return 3; // down
return -1;
}


The problem with the current code is that there is no displacement after a collision has been detected on one of the axis and thus when the player's rectangle intersects with the block's rectangle, the positional check is done on both sides without calculating which direction's depth is more prevalent.

Since these checks are not separated once the player enters a block from below, both the vertical and horizontal movement are blocked since your current conditions check for both after one another.

I would advise that you do additional depth checking based on the rectangle intersections either on both axis at the same time or separately as suggested by Nils. (Which is the safer the and as far as I know cleaner way to do so.)

Answered by Razeal on December 3, 2020

You are not taking into account what direction you were moving in so this isn't very surprising.

The simplest way to handle this is to split your movement into horizontal and vertical movement. Move horizontally first. If you collide with something move the player back to where he was. Then move vertically and if you collide move the player back again.

This has the advantage that you can slide along walls as long as they are vertically or horizontally aligned.

Once this works you can make additional improvements like figuring out how far exactly you have to move an object back for it to not intersect anymore.

Guaranteeing that no two objects that can move intersect at any frame makes a lot of things easier to handle, since you don't need code to handle unstucking.

Answered by Nils Ole Timm on December 3, 2020