📄 level.cs
字号:
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 + -