示例#1
0
        /// <summary>
        /// Instantiates a player, puts him in the level, and remembers where to put him when he is resurrected.
        /// </summary>
        private Tile LoadStartTile(int x, int y)
        {
            if (Player != null)
            {
                throw new NotSupportedException("A level may only have one starting point.");
            }

            start  = RectangleExtensions.GetBottomCenter(GetTileBounds(x, y));
            Player = new Byakuya(this, start, graphicsDevice);


            return(new Tile(null, TileCollision.Passable));
        }
示例#2
0
        /// <summary>
        /// This is to handle tunneling from dashes. Considers the dash direction.
        /// </summary>
        protected void HandleDashCollisions()
        {
            // Get the player's bounding rectangle and find neighboring tiles.
            Rectangle 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;

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

            // For each potentially colliding tile,
            for (int x = leftTile; x <= rightTile; ++x)
            {
                for (int y = topTile; y <= bottomTile; ++y)
                {
                    // If this tile is collidable,
                    TileCollision collision = level.GetCollision(x, y);
                    if (collision == TileCollision.Impassable) // only cannot dash through impassable blocks
                    {
                        // Determine collision depth (with direction) and magnitude.
                        Rectangle tileBounds = level.GetTileBounds(x, y);

                        int dashDirection = 0;
                        if (dashState == DashState.dashLeft)
                        {
                            dashDirection = 1;
                        }
                        else if (dashState == DashState.dashRight)
                        {
                            dashDirection = 2;
                        }
                        else if (dashState == DashState.dashUp)
                        {
                            dashDirection = 3;
                        }
                        else if (dashState == DashState.dashDown)
                        {
                            dashDirection = 4;
                        }

                        Vector2 depth = RectangleExtensions.GetDashIntersectionDepth(bounds, tileBounds, dashDirection);
                        if (depth != Vector2.Zero)
                        {
                            float absDepthY = depth.Y; // GetDashIntersectionDepth should always return positive values
                            float absDepthX = depth.X; // GetDashIntersectionDepth should always return positive values

                            // Dash downwards
                            if (dashState == DashState.dashDown)
                            {
                                // If we crossed the top of a tile, we are on the ground.
                                if (previousBottom <= tileBounds.Top)
                                {
                                    isOnGround = true;
                                }

                                // Offset upwards
                                position = new Vector2(position.X, position.Y - absDepthY);
                            }
                            // Dash upwards
                            else if (dashState == DashState.dashUp)
                            {
                                // Offset downwards
                                position = new Vector2(position.X, position.Y + absDepthY);
                            }
                            // Dash right
                            else if (dashState == DashState.dashRight)
                            {
                                // Offset left
                                position = new Vector2(position.X - absDepthX, position.Y);
                            }
                            // Dash left
                            else if (dashState == DashState.dashLeft)
                            {
                                // Offset right.
                                position = new Vector2(position.X + absDepthX, position.Y);
                            }

                            // Perform further collisions with the new bounds.
                            bounds = BoundingRectangle;
                        }
                    }
                }
            }


            // Save the new bounds bottom.
            previousBottom = bounds.Bottom;
        }
示例#3
0
        /// <summary>
        /// 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.
        /// </summary>
        protected void HandleCollisions()
        {
            // Get the player's bounding rectangle and find neighboring tiles.
            Rectangle 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;

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

            // For each potentially colliding tile,
            for (int y = topTile; y <= bottomTile; ++y)
            {
                for (int x = leftTile; x <= rightTile; ++x)
                {
                    // If this tile is collidable,
                    TileCollision collision = level.GetCollision(x, y);
                    if (collision != TileCollision.Passable)
                    {
                        // Determine collision depth (with direction) and magnitude.
                        Rectangle tileBounds = level.GetTileBounds(x, y);
                        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 (absDepthY < absDepthX || collision == TileCollision.platform)
                            {
                                // If we crossed the top of a tile, we are on the ground.
                                if (previousBottom <= tileBounds.Top)
                                {
                                    isOnGround = 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;
                            }
                        }
                    }
                }
            }

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