⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 level.cs

📁 《3d游戏编程入门经典》中范例小游戏。使用C#+DirectX开发。
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.IO;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace Blockers
{
    /// <summary>
    /// The main level object for our game
    /// </summary>
    public class Level
    {
        #region Constants
        private const float Spacing = 3.35f;
        private const int SquareSize = 13;
        private const float StartingLocation = (Spacing * SquareSize) / 2.0f;
        #endregion

        #region Instance Data
        // The list of blocks that comprise the level
        private Block[] blocks = null;
        // The final color to win
        private BlockColor finalColor;
        // Store the player
        private Player currentPlayer = null;
        // Block index of the player
        private int playerIndex;
        // Total number of moves made so far
        private int totalMoves = 0;
        // Maximum moves allowed
        private int maxMoves = 0;

        // Maximum time allowed
        private float maxTime = 0.0f;
        // The amount of time that has currently elapsed
        private float elapsedTime = 0.0f;

        // Amount of time remaining
        private TimeSpan timeLeft;

        // Is the game over for any reason?
        private bool isGameOver = false;
        // Did you win the game once it was over?
        private bool isGameWon = false;
        // Is this the first game over?
        private bool isFirstGameOver = true;

        // Number of blocks (total)
        private int numberBlocks = 0;
        // Number of blocks that are currently correct
        private int numberCorrectBlocks = 0;
        #endregion

        #region Constructor
        /// <summary>
        /// Create a new instance of the level class
        /// </summary>
        public unsafe Level(int level, Device device, Player player)
        {
            // Check the params
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }

            // Store the current player object
            currentPlayer = player;

            // First we need to read in the level file.  Opening the file will throw an
            // exception if the file doesn't exist.
            using(FileStream levelFile = File.OpenRead(GameEngine.MediaPath + 
                        string.Format("Level{0}.lvl", level)))
            {

                // With the file open, read in the level data.  First, the maximum
                // amount of time you will have to complete the level
                byte[] maxTimeData = new byte[sizeof(float)];
                levelFile.Read(maxTimeData, 0, maxTimeData.Length);
                maxTime = BitConverter.ToSingle(maxTimeData, 0); 

                // Now read in the maximum moves item
                byte[] maxMoveData = new byte[sizeof(int)];
                levelFile.Read(maxMoveData, 0, maxMoveData.Length);
                maxMoves = BitConverter.ToInt32(maxMoveData, 0); 

                // Determine how many colors will be used.
                byte[] numColorsData = new byte[sizeof(int)];
                levelFile.Read(numColorsData, 0, numColorsData.Length);
                int numColors = BitConverter.ToInt32(numColorsData, 0); 

                // Create the block of colors now
                BlockColor[] colors = new BlockColor[numColors];
                for (int i = 0; i < colors.Length; i++)
                {
                    colors[i] = (BlockColor)levelFile.ReadByte();
                }

                // Get the final color now
                finalColor = (BlockColor)levelFile.ReadByte();

                // Determine if the colors will rotate.
                byte[] rotateColorData = new byte[sizeof(bool)];
                levelFile.Read(rotateColorData, 0, rotateColorData.Length);
                bool rotateColor = BitConverter.ToBoolean(rotateColorData, 0); 

                // Create the array of blocks now to form the level
                blocks = new Block[SquareSize * SquareSize];

                int blockIndex = 0;

                for (int j = 0; j < SquareSize; j++)
                {
                    for (int i = 0; i < SquareSize; i++)
                    {
                        byte tempBlockColor = (byte)levelFile.ReadByte();

                        if (tempBlockColor != 0xff)
                        {
                            Block b = new Block(device, colors, tempBlockColor, rotateColor);
                            b.Position = new Vector3(-StartingLocation + 
                                (Spacing * i), -1.5f, 
                                -StartingLocation + (Spacing * j));

                            blocks[blockIndex++] = b;
                        }
                        else
                        {
                            blockIndex++;
                        }
                    }
                }

                // Get the default player starting position
                byte[] playerIndexData = new byte[sizeof(int)];
                levelFile.Read(playerIndexData, 0, playerIndexData.Length);
                playerIndex = BitConverter.ToInt32(playerIndexData, 0); 
            }
            UpdatePlayerAndBlock(true, playerIndex);

        }
        #endregion

        #region Player Movement
        /// <summary>
        /// Called when a key was pressed for a level
        /// </summary>
        public void OnKeyPress(System.Windows.Forms.Keys key)
        {
            // Is the player trying to move?
            switch(key)
            {
                case System.Windows.Forms.Keys.Right:
                    MovePlayerX(true);
                    break;
                case System.Windows.Forms.Keys.Left:
                    MovePlayerX(false);
                    break;
                case System.Windows.Forms.Keys.Up:
                    MovePlayerZ(false);
                    break;
                case System.Windows.Forms.Keys.Down:
                    MovePlayerZ(true);
                    break;
            }
        }
        /// <summary>
        /// Update the player and block for the current player index
        /// </summary>
        private bool UpdatePlayerAndBlock(bool force, int newPlayerIndex)
        {
            // Get the block the current player is over
            Block b = blocks[newPlayerIndex] as Block;
            
            if (force)
            {
                // Move the player to that position
                currentPlayer.Position = new Vector3(b.Position.X, 0, b.Position.Z);
            }
            else
            {
                // Move the player to that position
                if (!currentPlayer.MoveTo(new Vector3(b.Position.X, 0, b.Position.Z)))
                {
                    // The player can't move here yet, he's still moving, just exit this method
                    return false;
                }
            }

            // Update the color of this block
            b.SelectNextColor();
            return true;
        }
        /// <summary>
        /// Can the player move horizontally
        /// </summary>
        /// <param name="right">Is the player moving right</param>
        /// <returns>true if the move can be made; false otherwise</returns>
        private bool CanPlayerMoveHorizontal(bool right)
        {
            if ( ((playerIndex % SquareSize) == 0) && (!right))
            {
                return false;
            }
            else if ( ((playerIndex % SquareSize) == (SquareSize - 1)) && (right))
            {
                return false;
            }

            // Check to see if there is a piece in the new position
            return (blocks[playerIndex + ((right) ? 1 : -1)] != null);
        }
        /// <summary>
        /// Can the player move vertically
        /// </summary>
        /// <param name="pos">Is the player moving in the positive z direction</param>
        /// <returns>true if the move can be made; false otherwise</returns>
        private bool CanPlayerMoveVertical(bool pos)
        {
            if ( ((playerIndex / SquareSize) == 0) && (pos))
            {
                return false;
            }
            else if ( ((playerIndex / SquareSize) == (SquareSize - 1)) && (!pos))
            {
                return false;
            }

            return (blocks[playerIndex + ((pos) ? -SquareSize : SquareSize)] != null);
        }

        /// <summary>
        /// Update the player's position vertically
        /// </summary>
        /// <param name="pos">Is the player moving in the positive z direction</param>
        /// <returns>true if the move was made; false otherwise</returns>
        public bool MovePlayerZ(bool pos)
        {
            if (isGameOver)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -