Platformer.Player.HandleCollisions C# (CSharp) Method

HandleCollisions() private method

Detects and resolves all collisions between the player and his neighboring tiles. When a collision is detected, the player is pushed away along one axis to prevent overlapping. There is some special logic for the Y axis to handle platforms which behave differently depending on direction of movement.
private HandleCollisions ( ) : void
return void
        private void HandleCollisions()
        {
            // Get the player's bounding rectangle and find neighboring tiles.
            RectangleF bounds = BoundingRectangle;
            int leftTile = (int)Math.Floor((float)bounds.Left / Tile.Width);
            int rightTile = (int)Math.Ceiling(((float)bounds.Right / Tile.Width)) - 1;
            int topTile = (int)Math.Floor((float)bounds.Top / Tile.Height);
            int bottomTile = (int)Math.Ceiling(((float)bounds.Bottom / Tile.Height)) - 1;

            List<Tile> candidateTiles = new List<Tile>();
            for (int y = topTile; y <= bottomTile; ++y)
            {
                for (int x = leftTile; x <= rightTile; ++x)
                {
                    Tile tile = level.getTile(x, y);
                    candidateTiles.Add(tile);
                }
            }
            candidateTiles.AddRange(level.MoveableTiles);

            // Reset flag to search for ground collision.
            isOnGround = false;

            bool movedByTile = false; // Ensure only none tile can move the player at a time

            // For each potentially colliding tile,
            foreach(Tile tile in candidateTiles)
            {
                if (tile == null)
                    continue;

                // If this tile is collidable,
                TileCollision collision = tile.Collision;
                if (collision != TileCollision.Passable)
                {
                    // Determine collision depth (with direction) and magnitude.
                    RectangleF tileBounds = tile.Sprite.Bounds;
                    Vector2 depth = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds);
                    if (depth != Vector2.Zero)
                    {
                        float absDepthX = Math.Abs(depth.X);
                        float absDepthY = Math.Abs(depth.Y);

                        // Resolve the collision along the shallow axis.
                        if (collision != TileCollision.Death && collision != TileCollision.Water && collision != TileCollision.Ladder && (absDepthY < absDepthX || collision == TileCollision.Platform))
                        {
                            // If we crossed the top of a tile, we are on the ground.

                            // This needs to change for ladder mechanic
                            //if (previousBottom <= tileBounds.Top)
                            if(tileBounds.Top - previousBottom < 0.001f) // 0.001 is the delta for floating point comparisons
                            {
                                isOnGround = true;
                                isClimbing = false;
                                isJumping = false;

                            }

                            // Perform moving tile collition
                            if (tile is MoveableTile && !movedByTile)
                            {
                                MoveableTile moveableTile = (MoveableTile)tile;
                                position += moveableTile.FrameVelocity;
                                isOnGround = true;
                                movedByTile = true;
                            }

                            // Ignore platforms, unless we are on the ground.
                            if (collision == TileCollision.Impassable || IsOnGround)
                            {
                                // Resolve the collision along the Y axis.
                                Position = new Vector2(Position.X, Position.Y + depth.Y);

                                // Perform further collisions with the new bounds.
                                bounds = BoundingRectangle;
                            }
                        }
                        else if (collision == TileCollision.Impassable) // Ignore platforms.
                        {

                            // Resolve the collision along the X axis.
                            Position = new Vector2(Position.X + depth.X, Position.Y);

                            // Perform further collisions with the new bounds.
                            bounds = BoundingRectangle;
                        }
                        else if (isAlive && collision == TileCollision.Ladder && !isClimbing)
                        {
                            //when we are walking in front of a ladder, or falling past a ladder
                            isClimbing = true;

                            // Resolve the collision along the Y axis
                            Position = new Vector2(Position.X, Position.Y);

                            // Future collisions with the new bounds
                            bounds = BoundingRectangle;
                        }
                        else if (isAlive && collision == TileCollision.Death) // Something that kills you!
                        {
                            if(absDepthY > tile.Sprite.Height/2)
                                OnKilled("You touched something stupid!", DeathType.Spike);
                        }
                        else if (isAlive && collision == TileCollision.Water)
                        {
                            RectangleF tileRect = tile.Sprite.Bounds;
                            RectangleF headRect = BoundingRectangle;
                            headRect.Height /= 8; // Take the bounds of the head only

                            if (tileRect.Intersects(headRect))
                                OnKilled("You drowned under water", DeathType.Water);
                        }
                    }
                }
            }

            // Save the new bounds bottom.
            previousBottom = bounds.Bottom;
        }