Search code examples
c#collisionbounce

Collision detection bouncing problem c#


So I got my collision detection working, but for some reason the player seems to go intro the ground 1 frame then jump out of it in the next frame and then fall down as its supposed to.

Code I use for the collision detection

        void DoCollisions()
    {
        onGround = false;
        Position.Y += Velocity.Y;
        Vector2 tileCollision = GetTileCollision();
        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            onGround = true;
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Position.Y -= Velocity.Y;
            Velocity.Y = 0;
            Position.Y += collisionDepth.Y;

        }

        Position.X += Velocity.X;
        tileCollision = GetTileCollision();
        if (tileCollision.X != -1 || tileCollision.Y != -1)
        {
            Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                new Rectangle(
                    tileCollision.X * World.tileEngine.TileWidth,
                    tileCollision.Y * World.tileEngine.TileHeight,
                    World.tileEngine.TileWidth,
                    World.tileEngine.TileHeight
                )
            );
            Position.X -= Velocity.X;
            Velocity.X = 0;
            Position.X += collisionDepth.X;

        }
    }

    Vector2 GetTileCollision()
    {
        int topLeftTileX = (int)(CollisionRectangle.TopLeft.X / World.tileEngine.TileWidth);
        int topLeftTileY = (int)(CollisionRectangle.TopLeft.Y / World.tileEngine.TileHeight);
        int BottomRightTileX = (int)(CollisionRectangle.DownRight.X / World.tileEngine.TileWidth);
        int BottomRightTileY = (int)(CollisionRectangle.DownRight.Y / World.tileEngine.TileHeight);

        for (int i = topLeftTileX; i <= BottomRightTileX; i++)
        {
            for (int j = topLeftTileY; j <= BottomRightTileY; j++)
            {
                if (World.tileEngine.TileIsSolid(i, j))
                {
                    return new Vector2(i,j);
                }
            }
        }

        return new Vector2(-1,-1);
    }

Solution

  • Using just the Y direction as an example, at first glance it seems that you are adjusting Y twice, once before the collision check, then when you get a collision you revert the Y and push the object out by collisionDepth

    You should probably not be reverting the Y, if the collisionDepth.Y indicates that you are intersecting the ground you should just push your object back by the depth amount, which would put you flush against the ground.

            if (tileCollision.X != -1 || tileCollision.Y != -1)
            {
                onGround = true;
                Vector2 collisionDepth = CollisionRectangle.DepthIntersection(
                    new Rectangle(
                        tileCollision.X * World.tileEngine.TileWidth,
                        tileCollision.Y * World.tileEngine.TileHeight,
                        World.tileEngine.TileWidth,
                        World.tileEngine.TileHeight
                    )
                );
                Velocity.Y = 0;
                // Depending on your coordinate system this should
                // be either + or - collisionDepth.Y
                Position.Y += collisionDepth.Y;
            }