A set of helpful methods for working with rectangles.
Example #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));
        }
Example #2
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.");
            }

            Rectangle rect = new Rectangle(x * Tile.Width, y * Tile.Height, Tile.Width, Tile.Height);
            Vector2   c    = new Vector2(rect.X + rect.Width / 2.0f, rect.Bottom);

            start  = RectangleExtensions.GetBottomCenter(GetBounds(x, y));
            player = new Player(this, start);

            return(new Tile(null, TileCollision.Passable));
        }
Example #3
0
        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 = game.CurrentLevel.GetCollision(x, y);
                    if (collision != TileCollision.Passable)
                    {
                        // Determine collision depth (with direction) and magnitude.
                        Rectangle tileBounds = game.CurrentLevel.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 || collision == TileCollision.Impassable || IsOnGround)
                            {
                                this.Explode();
                                break;
                            }
                        }
                    }
                }
            }

            // Save the new bounds bottom.
            previousBottom = bounds.Bottom;
        }
Example #4
0
        private Rectangle HandleCollision(Rectangle bounds, TileCollision collision, Rectangle tileBounds)
        {
            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;
                }
            }
            return(bounds);
        }
Example #5
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;
        }
Example #6
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[] ltArray = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 };
            int[] rtArray = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
            int[] ttArray = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
            int[] btArray = { 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };

            int leftTile   = 0;
            int rightTile  = 0;
            int topTile    = 0;
            int bottomTile = 0;

            //Vector2 drawPosn = GetDrawPosn();
            Vector2 collPosn = GetCollPosn();
            //if (drawPosn.X < 0)
            //{
            //    leftTile = drawPosn.X < -4 ? -1 : 0;
            //}
            //else
            //{
            int idxX = (int)collPosn.X;
            int quoX = (int)(idxX / Tile.Size.X);
            int remX = (int)(idxX % Tile.Size.X);

            if (remX < 0)
            {
                remX = 0;
            }
            int idxLeftTile  = ltArray[remX];
            int idxRightTile = rtArray[remX];

            leftTile  = idxLeftTile + quoX;
            rightTile = idxRightTile + quoX;
            //}

            //if (drawPosn.Y < 0)
            //{
            //    topTile = drawPosn.Y < -12 ? -1 : 0;
            //}
            //else
            //{
            int idxY = (int)collPosn.Y;
            int quoY = (int)(idxY / Tile.Size.Y);
            int remY = (int)(idxY % Tile.Size.Y);

            // this won't crash at least but will go off the sides
            if (remY < 0)
            {
                remY = 0;
            }
            int idxTopTile    = ttArray[remY];
            int idxBottomTile = btArray[remY];

            topTile    = idxTopTile + quoY;
            bottomTile = idxBottomTile + quoY;
            //}

            int leftTile2   = (int)Math.Floor((float)bounds.Left / Tile.Width);
            int rightTile2  = (int)Math.Ceiling(((float)bounds.Right / Tile.Width)) - 1;
            int topTile2    = (int)Math.Floor((float)bounds.Top / Tile.Height);
            int bottomTile2 = (int)Math.Ceiling(((float)bounds.Bottom / Tile.Height)) - 1;

            if (leftTile != leftTile2 || rightTile != rightTile2 || topTile != topTile2 || bottomTile != bottomTile2)
            {
                //String msg = String.Format("(X,Y)=({0},{1}), L:{2} R:{3} T:{4} B:{5}", (int)position.X, (int)position.Y, leftTile, rightTile, topTile, bottomTile);
                //String msg = String.Format("BoundL:{0} BoundT:{1} BoundW:{2} BoundH:{3}", bounds.Left, bounds.Top, bounds.Width, bounds.Height);
                //Logger.Info(msg);
            }

            if (shouldLog)
            {
                //String msg = String.Format("(X,Y)=({0},{1}), L:{2} R:{3} T:{4} B:{5}", (int) position.X, (int) position.Y, leftTile, rightTile, topTile, bottomTile);
                //String msg = String.Format("BoundL:{0} BoundT:{1} BoundW:{2} BoundH:{3}", bounds.Left, bounds.Top, bounds.Width, bounds.Height);
                //Logger.Info(msg);
            }

            // 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;
        }
Example #7
0
        /// <summary>
        /// Handles the collisions of bullet against another player.
        /// </summary>
        private void HandleCollisions()
        {
            //check against tile
            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 = Game.CurrentLevel.GetCollision(x, y);
                    if (collision != TileCollision.Passable)
                    {
                        // Determine collision depth (with direction) and magnitude.
                        Rectangle tileBounds = Game.CurrentLevel.GetBounds(x, y);
                        Vector2   depth      = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds);
                        if (depth != Vector2.Zero)
                        {
                            if (collision == TileCollision.Impassable) // Ignore platforms.
                            {
                                this.Reset();
                                return;
                            }
                        }
                    }
                }
            }

            foreach (Player player in PlatformerGame.Players)
            {
                //do not check against the owner of the bullet
                if (player != _player)
                {
                    if (this.BoundingRectangle.Intersects(player.BoundingRectangle))
                    {
                        //Rolling players are invulnarable.
                        //Ignore dead players
                        if (!player.IsRolling && player.IsAlive)
                        {
                            float dir = (Flip == SpriteEffects.None) ? 1.0f : -1.0f;
                            player.Hit(BULLET_DAMAGE, dir, _player);
                            this.Reset();
                        }
                    }
                }
            }

            List <Enemy> enemies = game.CurrentLevel.Enemies;

            foreach (Bowser enemy in enemies)
            {
                if (enemy.IsAlive)
                {
                    if (this.BoundingRectangle.Intersects(enemy.BoundingRectangle))
                    {
                        int dir = (Flip == SpriteEffects.None) ? 1 : -1;
                        enemy.Hit(BULLET_DAMAGE, dir);
                        this.Reset();
                    }
                }
            }
        }