コード例 #1
0
 public static void MoveDestructableObject(ref Vector2 velocity, ref Vector2 position, int width, int height, ref bool active, float elapsedTime)
 {
     #region MOVE HORIZONTALLY
     //move horizontally
     position.X += velocity.X * elapsedTime;
     int topRow   = (int)MathHelper.Clamp(position.Y / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
     int btmRow   = (int)MathHelper.Clamp((position.Y + height - 1) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
     int leftCol  = (int)MathHelper.Clamp(position.X / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
     int rightCol = (int)MathHelper.Clamp((position.X + width - 1) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
     //check right-hand side
     if (velocity.X > 0)
     {
         for (int row = topRow; row <= btmRow; row++)
         {
             if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[row, rightCol].isSolid())
             {
                 position.X = rightCol * Tile.tileSize - width;
                 active     = false;
                 return;
             }
         }
     }
     //check left-hand side
     else if (velocity.X < 0)
     {
         for (int row = topRow; row <= btmRow; row++)
         {
             if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[row, leftCol].isSolid())
             {
                 position.X = (leftCol + 1) * Tile.tileSize;
                 active     = false;
                 return;
             }
         }
     }
     #endregion
     #region MOVE VERTICALLY
     //move vertically
     velocity.Y += (gravityAcceleration - velocity.Y * airFrictionCoeff) * elapsedTime;
     position.Y += velocity.Y * elapsedTime;
     topRow      = (int)MathHelper.Clamp(position.Y / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
     btmRow      = (int)MathHelper.Clamp((position.Y + height - 1) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
     leftCol     = (int)MathHelper.Clamp(position.X / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
     rightCol    = (int)MathHelper.Clamp((position.X + width - 1) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
     //check bottom
     if (velocity.Y > 0)
     {
         for (int col = leftCol; col <= rightCol; col++)
         {
             if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[btmRow, col].isSolid())
             {
                 position.Y = btmRow * Tile.tileSize - height;
                 active     = false;
                 return;
             }
         }
     }
     //check top
     else if (velocity.Y < 0)
     {
         for (int col = leftCol; col <= rightCol; col++)
         {
             if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[topRow, col].isSolid())
             {
                 position.Y = (topRow + 1) * Tile.tileSize;
                 active     = false;
                 return;
             }
         }
     }
     #endregion
     #region COLLISION WITH MOVING PLATFORMS
     //coliisions with moving platforms
     for (int i = 0; i < PlatformsManager.platformsRoomManagers[(int)RoomsManager.CurrentRoom].movingPlatforms.Length; i++)
     {
         MovingPlatform p = PlatformsManager.platformsRoomManagers[(int)RoomsManager.CurrentRoom].movingPlatforms[i];
         if (!p.Transparent &&
             position.X + width > p.Position.X &&
             position.X < p.Position.X + p.width &&
             position.Y + height - p.Position.Y >= 0 &&
             position.Y + height - p.Position.Y <= velocity.Y * elapsedTime - p.Shift.Y)
         {
             position.Y = p.Position.Y - height;
             active     = false;
             return;
         }
     }
     #endregion
 }
コード例 #2
0
        //move player based on his current velocity and check for collisions with solid tiles
        static void Move(float elapsedTime)
        {
            Vector2 totalSpeed = new Vector2();

            #region CHECK IF IS STILL ON THE WALL
            //CHECK IF IS STILL ON THE WALL
            int topRow   = (int)MathHelper.Clamp(position.Y / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
            int btmRow   = (int)MathHelper.Clamp((position.Y + height - 0.001f) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
            int leftCol  = (int)MathHelper.Clamp((position.X - 1) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
            int rightCol = (int)MathHelper.Clamp((position.X + 1 + width - 0.001f) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
            if (isOnTheWall)
            {
                isOnTheWall = false;
                if (isFacingRight)
                {
                    for (int row = topRow; row <= btmRow; row++)
                    {
                        if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[row, rightCol].isSolid())
                        {
                            isOnTheWall = true;
                        }
                    }
                }
                else
                {
                    for (int row = topRow; row <= btmRow; row++)
                    {
                        if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[row, leftCol].isSolid())
                        {
                            isOnTheWall = true;
                        }
                    }
                }
            }
            #endregion
            #region CALCULATE VELOCITIES
            //CALCULATE X VELOCITIES
            //total speed is a ocnbination of jumpSpeed and movement speed
            if (isWallJumping)
            {
                if (Math.Abs(jumpSpeed.X) > maxHorizontalMovementSpeed)
                {
                    totalSpeed.X = jumpSpeed.X;
                }
                else
                {
                    if (Math.Sign(jumpSpeed.X) == -Math.Sign(horizontalMovementSpeed))
                    {
                        if (Math.Abs(jumpSpeed.X) >= maxHorizontalMovementSpeed / 2f)
                        {
                            totalSpeed.X = jumpSpeed.X;
                        }
                        else
                        {
                            isWallJumping = false;
                            jumpSpeed.X   = 0;
                            totalSpeed.X  = horizontalMovementSpeed;
                        }
                    }
                    else
                    {
                        totalSpeed.X = jumpSpeed.X + horizontalMovementSpeed;
                        totalSpeed.X = MathHelper.Clamp(totalSpeed.X, -maxHorizontalMovementSpeed, maxHorizontalMovementSpeed);
                    }
                }
                jumpSpeed.X -= 2f * jumpSpeed.X * Gravity.airFrictionCoeff * elapsedTime;//2 is a magic number
            }
            else if (!isTouchingTheGround)
            {
                if (Math.Sign(jumpSpeed.X) == -Math.Sign(horizontalMovementSpeed))
                {
                    totalSpeed.X = horizontalMovementSpeed;
                }
                else if (Math.Abs(jumpSpeed.X) > maxHorizontalMovementSpeed)
                {
                    totalSpeed.X = jumpSpeed.X;
                    jumpSpeed.X -= 2 * jumpSpeed.X * Gravity.airFrictionCoeff * elapsedTime;//2 is a magic number
                }
                else
                {
                    totalSpeed.X = jumpSpeed.X + horizontalMovementSpeed;
                    totalSpeed.X = MathHelper.Clamp(totalSpeed.X, -maxHorizontalMovementSpeed, maxHorizontalMovementSpeed);
                    jumpSpeed.X -= 6 * jumpSpeed.X * Gravity.airFrictionCoeff * elapsedTime;//6 is a magic number
                }
            }
            else
            {
                totalSpeed.X = horizontalMovementSpeed;
            }
            horizontalMovementSpeed = 0;
            if (totalSpeed.X > 0)
            {
                isFacingRight = true;
            }
            else if (totalSpeed.X < 0)
            {
                isFacingRight = false;
            }
            //CALCULATE Y VELOCITIES
            if (!isOnMovingPlatform)
            {
                if (isOnTheWall)
                {
                    if (Gravity.gravityAcceleration - jumpSpeed.Y * Gravity.wallFrictionCoeff > 0)
                    {
                        jumpSpeed.Y += (Gravity.gravityAcceleration - jumpSpeed.Y * Gravity.wallFrictionCoeff) * elapsedTime;
                    }
                }
                else
                {
                    if (Gravity.gravityAcceleration - jumpSpeed.Y * Gravity.airFrictionCoeff > 0)
                    {
                        jumpSpeed.Y += (Gravity.gravityAcceleration - jumpSpeed.Y * Gravity.airFrictionCoeff) * elapsedTime;
                    }
                }
                if (jumpSpeed.Y > Gravity.gravityAcceleration * elapsedTime * 15)
                {
                    isTouchingTheGround = false;
                    isOnMovingPlatform  = false;
                    if (currentAnimation != AnimationTypes.die && currentAnimation != AnimationTypes.attack && !isOnTheWall)
                    {
                        currentAnimation = AnimationTypes.fall;
                    }
                }
                totalSpeed.Y = jumpSpeed.Y;
            }
            else
            {
                totalSpeed += PlatformsManager.platformsRoomManagers[(int)RoomsManager.CurrentRoom].movingPlatforms[PlatformsManager.platformIndex].Shift / elapsedTime;
            }
            #endregion
            position.X += totalSpeed.X * elapsedTime;
            #region CHECK COLLISION WITH SOLID TILES
            //check collisions with solid tiles
            topRow   = (int)MathHelper.Clamp(position.Y / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
            btmRow   = (int)MathHelper.Clamp((position.Y + height - 0.001f) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
            leftCol  = (int)MathHelper.Clamp((position.X - 1) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
            rightCol = (int)MathHelper.Clamp((position.X + 1 + width - 0.001f) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
            //check right-hand side
            if (totalSpeed.X >= 0)
            {
                for (int row = topRow; row <= btmRow; row++)
                {
                    if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[row, rightCol].isSolid())
                    {
                        position.X = rightCol * Tile.tileSize - width;
                        if (!isTouchingTheGround)
                        {
                            isWallJumping = false;
                            if (jumpSpeed.Y > 0 && !isOnTheWall)
                            {
                                jumpSpeed.Y = 0;
                            }
                            if (jumpSpeed.Y > initialJumpSpeed.Y * 0.2f)
                            {
                                isOnTheWall = true;
                            }
                            jumpSpeed.X = 0;
                        }
                        break;
                    }
                }
            }
            //check left-hand side
            if (totalSpeed.X <= 0)
            {
                for (int row = topRow; row <= btmRow; row++)
                {
                    if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[row, leftCol].isSolid())
                    {
                        position.X = (leftCol + 1) * Tile.tileSize;
                        if (!isTouchingTheGround)
                        {
                            isWallJumping = false;
                            if (jumpSpeed.Y > 0 && !isOnTheWall)
                            {
                                jumpSpeed.Y = 0;
                            }
                            if (jumpSpeed.Y > initialJumpSpeed.Y * 0.2f)
                            {
                                isOnTheWall = true;
                            }
                            jumpSpeed.X = 0;
                        }
                        break;
                    }
                }
            }
            #endregion
            position.Y += totalSpeed.Y * elapsedTime;
            #region CHECK COLLISIONS WITH TILES
            topRow   = (int)MathHelper.Clamp(position.Y / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
            btmRow   = (int)MathHelper.Clamp((position.Y + height - 0.001f) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomHeightTiles - 1);
            leftCol  = (int)MathHelper.Clamp(position.X / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
            rightCol = (int)MathHelper.Clamp((position.X + width - 0.001f) / Tile.tileSize, 0, MapsManager.maps[(int)RoomsManager.CurrentRoom].roomWidthTiles - 1);
            //check bottom
            if (totalSpeed.Y > 0)
            {
                int span = ((int)(totalSpeed.Y * elapsedTime + Tile.tileSize) / Tile.tileSize);
                for (int i = span - 1; i >= 0; i--)
                {
                    for (int col = leftCol; col <= rightCol; col++)
                    {
                        if (btmRow - i < 0)
                        {
                            break;
                        }
                        if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[btmRow - i, col].isSolid())
                        {
                            position.Y          = (btmRow - i) * Tile.tileSize - height;
                            jumpSpeed.Y         = 0;
                            jumpSpeed.X         = 0;
                            isTouchingTheGround = true;
                            isOnMovingPlatform  = false;
                            canDoubleJump       = true;
                            isOnTheWall         = false;
                            isWallJumping       = false;
                            i = 0;
                            break;
                        }
                    }
                }
            }
            //check top
            else if (totalSpeed.Y < 0)
            {
                for (int col = leftCol; col <= rightCol; col++)
                {
                    if (MapsManager.maps[(int)RoomsManager.CurrentRoom].array[topRow, col].isSolid())
                    {
                        position.Y         = (topRow + 1) * Tile.tileSize;
                        jumpSpeed.Y        = 0;
                        isOnMovingPlatform = false;
                        break;
                    }
                }
            }
            #endregion
            #region CHECK COLLISION WITH MOVING PLATFORM
            //check collisions with moving platforms
            if (!isOnMovingPlatform)
            {
                for (int i = 0; i < PlatformsManager.platformsRoomManagers[(int)RoomsManager.CurrentRoom].movingPlatforms.Length; i++)
                {
                    MovingPlatform p = PlatformsManager.platformsRoomManagers[(int)RoomsManager.CurrentRoom].movingPlatforms[i];
                    if (!p.Transparent &&
                        position.X + width > p.Position.X &&
                        position.X < p.Position.X + p.width &&
                        position.Y + height - p.Position.Y >= 0 &&
                        position.Y + height - p.Position.Y <= totalSpeed.Y * elapsedTime - p.Shift.Y)
                    {
                        isOnMovingPlatform             = true;
                        position.Y                     = p.Position.Y - height;
                        jumpSpeed.Y                    = 0;
                        jumpSpeed.X                    = 0;
                        PlatformsManager.platformIndex = i;
                        isTouchingTheGround            = true;
                        canDoubleJump                  = true;
                        isOnTheWall                    = false;
                        isWallJumping                  = false;
                        return;
                    }
                }
            }
            else
            {
                MovingPlatform p = PlatformsManager.platformsRoomManagers[(int)RoomsManager.CurrentRoom].movingPlatforms[PlatformsManager.platformIndex];
                if (position.X - p.Position.X <= -width || position.X - p.Position.X >= p.width || p.Transparent)
                {
                    isOnMovingPlatform = false;
                }
            }
            #endregion
        }