Collisions not working as intended

Posted by Stan on Game Development See other posts from Game Development or by Stan
Published on 2011-11-22T18:50:15Z Indexed on 2011/11/23 2:10 UTC
Read the original article Hit count: 394

Filed under:
|
|

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.

© Game Development or respective owner

Related posts about XNA

Related posts about c#