예제 #1
0
        private void Collisions()
        {
            Rectangle bounds = BoundingRect;
            int       left   = (int)Math.Floor((float)bounds.Left / Tiles.TileWidth);
            int       right  = (int)Math.Ceiling(((float)bounds.Right / Tiles.TileWidth)) - 1;
            int       top    = (int)Math.Floor((float)bounds.Top / Tiles.TileHeight);
            int       bottom = (int)Math.Ceiling(((float)bounds.Bottom / Tiles.TileHeight)) - 1;

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

            // For each potentially colliding tile,
            for (int y = top; y <= bottom; ++y)
            {
                for (int x = left; x <= right; ++x)
                {
                    // If this tile is collidable,
                    TilesCollision collision = Level.Collision(x, y);
                    if (collision != TilesCollision.Passable)
                    {
                        // Determine collision depth (with direction) and magnitude.
                        Rectangle tileBounds = Level.Bounds(x, y);
                        Vector2   depth      = RectangleExtensions.IntersectionDepth(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 (absDepthY < absDepthX || collision == TilesCollision.Platform)
                            {
                                // If we crossed the top of a tile, we are on the ground.
                                if (PrevBottom <= tileBounds.Top)
                                {
                                    isGround = true;
                                }

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

                                    // Perform further collisions with the new bounds.
                                    bounds = BoundingRect;
                                }
                            }
                            else if (collision == TilesCollision.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 = BoundingRect;
                            }
                            else if (collision == TilesCollision.Lava)
                            {
                                level.Restart();
                                health -= 1;

                                if (health <= 0)
                                {
                                    Kill(null);
                                }
                            }
                        }
                    }
                }
            }
            PrevBottom = bounds.Bottom;
        }