Beispiel #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(GetBounds(x, y));
            player = new Player(this, start);

            return(new Tile(null, TileCollision.Passable, TileMovement.Static));
        }
Beispiel #2
0
        /// <summary>
        /// Moves the platform along a path, waiting at either end.
        /// </summary>
        public void Update(GameTime gameTime)
        {
            bool mustmove = true;

            // Get the 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;

            // 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.GetBounds(x, y);
                        Vector2   depth      = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds);
                        if (depth != Vector2.Zero)
                        {
                            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
                            direction = (FaceDirection)(-(int)direction);
                            if (glidermovement == TileMovement.Vertical)
                            {
                                Position = new Vector2(Position.X, Position.Y + depth.Y);
                            }
                            else if (glidermovement == TileMovement.Horizontal)
                            {
                                Position = new Vector2(Position.X + depth.X, Position.Y);
                            }

                            mustmove = false;
                            break;
                        }
                    }
                }
                if (!mustmove)
                {
                    break;
                }
            }

            if (mustmove)
            {
                float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

                if (position.Y < 0.0f - bounds.Height)
                {
                    position = new Vector2(position.X, (level.Height * Tile.Height) + bounds.Height);
                }
                else if (position.Y > (level.Height * Tile.Height) + bounds.Height)
                {
                    position = new Vector2(position.X, 0.0f);
                }
                else
                {
                    if (glidermovement == TileMovement.Vertical)
                    {
                        Vector2 velocity = new Vector2(0.0f, (int)direction * moveSpeed * elapsed);
                        position = position + velocity;
                    }
                    else if (glidermovement == TileMovement.Horizontal)
                    {
                        Vector2 velocity = new Vector2((int)direction * moveSpeed * elapsed, 0.0f);
                        position = position + velocity;
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Detects and resolves collisions between the Player and the glidingPlatform nearest him.
        /// </summary>
        public void HandleGlidingPlatformCollisions()
        {
            // Did I just collide with a gliding platform?
            foreach (GlidingPlatform platform in Level.playerPlatforms)
            // To know this we have to check the list of platforms in
            // the camera's visible range
            // which we collected from the level calss
            {
                // We check if the player's feet intersect with the platform's surface.
                if (platform.Surface.Intersects(Feet))
                {
                    OnPlatform(platform); // If so, then this is the platform we want to save.
                }
            }

            // If I own a platform
            if (isOnPlatform == true)
            {
                // reset isOnPlatform for the purposes of evaluating it again.
                isOnPlatform = false;

                // Do they intersect?
                if (Feet.Intersects(platform.Surface))
                {
                    isOnPlatform = true;
                    //Yes they intersect. By how deep?
                    Vector2 depth = RectangleExtensions.GetIntersectionDepth(Feet, platform.Surface);

                    // Is it more than zero?
                    if (depth != Vector2.Zero)
                    {
                        // Yes they intersect and it is more than zero depth!
                        // Find out by how much.
                        float absDepthX = Math.Abs(depth.X);
                        float absDepthY = Math.Abs(depth.Y);

                        // Act as if we are on the ground if we were previously on the a platform.
                        if (previousBottom >= platform.Surface.Top)
                        {
                            isOnGround = true;
                        }

                        if (isOnPlatform)
                        {
                            // Resolve the collision along the Y axis.
                            Position = new Vector2(Position.X /*+ platform.Position.X*/, Position.Y - Math.Abs(depth.Y));
                        }
                    }
                }
            }

            // Check if the player's Y has moved through a platform's surface.
            foreach (GlidingPlatform platform in level.playerPlatforms)
            {
                if ((position.Y > platform.Surface.Top - 12) && (position.Y < platform.Surface.Top + 12) &&
                    (position.X > platform.Surface.Left - BoundingRectangle.Width / 2) &&
                    (position.X < platform.Surface.Right + BoundingRectangle.Width / 2) &&
                    (velocity.Y > 0)) // if the velocity is negative the player is jumping up.
                // If the player is jumping up, we don't want him to stick, only when moving down.

                // The speed the player moves with a MaxFallSpeed of 600.0f is 12 pixels per second.
                // If we don't check this condition, the player can jump right past the surface of the platform,
                // and the game will never know to make the player stick!
                {
                    OnPlatform(platform);
                    position.Y = platform.Surface.Top;
                }
            }

            previousBottom = BoundingRectangle.Bottom;
        }
Beispiel #4
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>
        private 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.GetBounds(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;
        }