Collisions not working as intended
- by Stan
I'm making a game, it's a terraria-like game, with 20x20 blocks, and you can place and remove those blocks. Now, I am trying to write collisions, but it isn't working as I want, the collision succesfully stops the player from going through the ground, but, when I press a key like A + S, that means if I walk down and left (Noclip is on atm), my player will go into the ground, bug up, and exit the ground somewhere else in the level. I made a video of it. The red text means which buttons I am pressing.
http://www.youtube.com/watch?v=mo4frZyNwOs
You see, if I press A and S together, I go into the ground.
Here is my collision code:
Vector2 collisionDist, normal;
private bool IsColliding(Rectangle body1, Rectangle body2)
{
normal = Vector2.Zero;
Vector2 body1Centre = new Vector2(body1.X + (body1.Width / 2), body1.Y + (body1.Height / 2));
Vector2 body2Centre = new Vector2(body2.X + (body2.Width / 2), body2.Y + (body2.Height / 2));
Vector2 distance, absDistance;
float xMag, yMag;
distance = body1Centre - body2Centre;
float xAdd = ((body1.Width) + (body2.Width)) / 2.0f;
float yAdd = ((body1.Height) + (body2.Height)) / 2.0f;
absDistance.X = (distance.X < 0) ? -distance.X : distance.X;
absDistance.Y = (distance.Y < 0) ? -distance.Y : distance.Y;
if (!((absDistance.X < xAdd) && (absDistance.Y < yAdd)))
return false;
xMag = xAdd - absDistance.X;
yMag = yAdd - absDistance.Y;
if (xMag < yMag)
normal.X = (distance.X > 0) ? xMag : -xMag;
else
normal.Y = (distance.Y > 0) ? yMag : -yMag;
return true;
}
private void PlayerCollisions()
{
foreach (Block blocks in allTiles)
{
collisionDist = Vector2.Zero;
if (blocks.Texture != airTile && blocks.Texture != stoneDarkTexture && blocks.Texture != stoneDarkTextureSelected && blocks.Texture != airTileSelected && blocks.Texture != doorTexture && blocks.Texture != doorTextureSelected)
{
if (IsColliding(player.plyRect, blocks.tileRect))
{
if (normal.Length() > collisionDist.Length())
{
collisionDist = normal;
}
player.Position.X += collisionDist.X;
player.Position.Y += collisionDist.Y;
break;
}
}
}
}
I got PlayerCollisions() running in my Update method.
As you can see it works partly, but if it runs perfectly, it would be awesome, though I have no idea how to fix this problem. Help would be greatly appreciated.
EDIT:
If I remove the break; it works partly, then it is just the thing that it spasms when it hits two or more blocks at once, like, if I touch 2/3 blocks at once, it does twice the force up. How can I make it so that it only does the force for one block, so it stays correct, and does not spasm? Thanks.