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: 486
        
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