Wednesday, October 4, 2017

xna - Collisions not working as intended



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 successfully 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.


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.




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...