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

📄 game.cs

📁 这个程序是基于c#平台的俄罗斯方框游戏。拿来共享。要求加分哦!
💻 CS
📖 第 1 页 / 共 2 页
字号:


using System;
using System.Drawing;
using Microsoft.Win32;

namespace AnotherBlock
{
	/// <summary>
	/// Represents a Tetris game engine.
	/// </summary>
	public class Game
	{
		/// <summary>
		/// Constant with the image width of the block unit (in pixels).
		/// </summary>
		public const int BlockImageWidth = 21;
		/// <summary>
		/// Constant with the image height of the block unit (in pixels).
		/// </summary>
		public const int BlockImageHeight = 21;
		/// <summary>
		/// Constant with the playing field width (in block units).
		/// </summary>
		public const int PlayingFieldWidth = 10;
		/// <summary>
		/// Constant with the playing field height (in block units).
		/// </summary>
		public const int PlayingFieldHeight = 20;
		/// <summary>
		/// Constante with the number of lines for each level.
		/// </summary>
		public const int LevelEveryLines = 12;

		/// <summary>
		/// Private attribute that holds the current game score.
		/// </summary>
		private int score = 0;
		/// <summary>
		/// Private attribute that holds the current game level.
		/// </summary>
		private short level = 1;
		/// <summary>
		/// Private attribute that holds the current number of completed lines.
		/// </summary>
		private int lines = 0;
		/// <summary>
		/// Private attribute that holds the current game state.
		/// </summary>
		private GameState gameState;
		/// <summary>
		/// Private attribute that holds the level where the game started.
		/// </summary>
		private short startLevel = 1;
		/// <summary>
		/// Private attribute that holds the current game pile.
		/// </summary>
		private Brick[,] pile = new Brick[(PlayingFieldWidth + 1), (PlayingFieldHeight + 1)];
		/// <summary>
		/// Private attribute that holds the current block.
		/// </summary>
		private Block currentBlock = new Block();
		/// <summary>
		/// Private attribute that holds the next block.
		/// </summary>
		private Block nextBlock = new Block();

		/// <summary>
		/// Class constructor that creates a game.
		/// </summary>
		public Game()
		{
			// Clears the game pile.
			ClearPile();
		}

		/// <summary>
		/// Class constructor that creates a game in a given level.
		/// </summary>
		/// <param name="level">The level where the game should start.</param>
		public Game(short level)
		{
			// Sets the level attribute to the game level where the game should start.
			this.level = level;
			// Sets the startLevel attribute to the game level where the game should start.
			startLevel = level;
			// Clears the game pile.
			ClearPile();
		}

		/// <summary>
		/// Readonly property that holds the score of the current game.
		/// </summary>
		public int Score
		{
			get
			{
				// Returns the value in the score attribute.
				return score;
			}
		}

		/// <summary>
		/// Readonly property that holds the level of the current game.
		/// </summary>
		public short Level
		{
			get
			{
				// Returns the value in the level attribute.
				return level;
			}
		}

		/// <summary>
		/// Readonly property that holds the number of complete lines in the current game.
		/// </summary>
		public int Lines
		{
			get
			{
				// Returns the value in the lines attribute.
				return lines;
			}
		}

		/// <summary>
		/// Property that holds and sets the current game state.
		/// </summary>
		/// <remarks>
		/// The game state can be "Running", "Paused" or "Over".
		/// </remarks>
		public GameState GameState
		{
			get
			{
				// Returns the value in the gameState attribute.
				return gameState;
			}
			set
			{
				// Checks if the current game state is "Over", and if the value to change is not "Over".
				if ((gameState == GameState.Over) && (value != GameState.Over))
				{
					// The current game state is "Over", and it's changing to something else than "Over".
					// Resets the score, level and lines.
					score = 0;
					level = startLevel;
					lines = 0;
					// Creates a new current block, and a new next block.
					currentBlock = new Block();
					nextBlock = new Block();
					// Clears the game pile.
					ClearPile();
				}

				// Sets the gameState attribute to the value.
				gameState = value;
			}
		}

		/// <summary>
		/// Method that moves the current block down one position.
		/// </summary>
		/// <returns>True if there was a hit on the ground or on the pile, false if there wasn't.</returns>
		public bool MoveCurrentBlockDown()
		{
			// Creates a "hit" flag, to check if the block has hit the pile or the ground.
			bool hit = false;

			// Increases the Top of the current block.
			currentBlock.Top++;

			// Checks if the current block has hit the ground.
			// COLLISION DETECTION
			if ((currentBlock.Top + currentBlock.Height) > PlayingFieldHeight)
			{
				// Current block has hit the ground.
				// Sets the "hit" flag to "true".
				hit = true;
			}
			else
			{
				// Checks if the current block has hit the pile.
				// COLLISION DETECTION
				for(int i = 0; i < currentBlock.Width; i++)
				{
					for(int j = 0; j < currentBlock.Height; j++)
					{
						int fx, fy;
						fx = currentBlock.Left + i;
						fy = currentBlock.Top + j;
						if ((currentBlock.Shape[i, j].Filled == true) && (pile[fx, (fy + 1)].Filled == true))
						{
							// Current block has hit the pile.
							// Sets the "hit" flag to "true".
							hit = true;
						}
					}
				}
			}

			// Checks if there was a hit.
			if (hit)
			{
				// There was a hit.
				// Puts the current block in the pile.
				MoveBlockToPile();
				// Checks if the current game state is not "Over".
				if (this.GameState != GameState.Over)
				{
					// Current game state is not "Over".
					// Creates a new block.
					CreateNewBlock();
				}
			}

			// Returns if there was a hit or not.
			return hit;
		}

		/// <summary>
		/// Method that moves the current block down until there is a hit.
		/// </summary>
		public void MoveCurrentBlockCompletelyDown()
		{
			// Moves the current block down until it has a hit.
			while(!MoveCurrentBlockDown());
		}

		/// <summary>
		/// Method that rotates the current block.
		/// </summary>
		/// <param name="clockwise">True if the block will be rotated clockwise, false if counterclockwise.</param>
		public void RotateCurrentBlock(bool clockwise)
		{
			// Creates a "canRotate" flag, to check if the block can be rotated.
			bool canRotate = true;

			// Rotates the current block.
			// This should be different. There should be an easy way to check FIRST if the block could
			// be rotated, and then rotate it. I'll study this later.
			currentBlock.Rotate(clockwise);

			// Checks if the current block could be rotated.
			// COLLISION DETECTION
			for(int i = 0; i < currentBlock.Width; i++)
			{
				for(int j = 0; j < currentBlock.Height; j++)
				{
					int fx, fy;
					fx = currentBlock.Left + i;
					fy = (currentBlock.Top + 1) + j;
					if ((currentBlock.Shape[i, j].Filled == true) && (pile[fx, fy].Filled == true))
					{
						// Current block can't be rotated.
						// Sets the "canRotate" flag to "false".
						canRotate = false;
					}
				}
			}

			// Checks if the block can't be rotated.
			if (!canRotate)
			{
				// Block can't be rotated.
				// Rotates the block back to its first position.
				currentBlock.Rotate(!clockwise);
			}
		}

		/// <summary>
		/// Method that moves the current block to the right or to the left.
		/// </summary>
		/// <param name="left">True if the block will be moved to the left, false if to the right.</param>
		public void MoveCurrentBlockSide(bool left)
		{
			// Creates a "canMove" flag, to check if the block can be moved to the sides.
			bool canMove = true;

			// Checks if the block is to be moved to the left.
			if (left)
			{
				// The block is to be moved to the left.
				// Checks if the block is not already at the most left of the playing field.
				if (currentBlock.Left > 0)
				{
					// Block is not at the most left of the playing field.
					// Checks if the current block can move to the left.
					// COLLISION DETECTION
					for(int i = 0; i < currentBlock.Width; i++)
					{
						for(int j = 0; j < currentBlock.Height; j++)
						{
							int fx, fy;
							fx = currentBlock.Left + i;
							fy = (currentBlock.Top + 1) + j;
							if ((currentBlock.Shape[i, j].Filled == true) && (pile[(fx - 1), fy].Filled == true))
							{

⌨️ 快捷键说明

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