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

📄 figure.cs

📁 game tetris :), this file is a little too big but it s run well, besides, it also has file descripti
💻 CS
字号:
using System;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace GATetrisControl
{
	#region Enums

	public enum RotateDirection
	{
		ClockWise,
		AntiClockWise
	}

	public enum RotateAngle
	{
		Deg0,
		Deg90,
		Deg180,
		Deg270
	}

	public enum MoveDirection
	{
		Left,
		Right,
		Down,
		Rotate
	}
	#endregion

	public class Figure
	{
		#region Constructor

		public Figure(TetrisGrid grid)
		{
			parent = grid;
			columns = parent.settings.columns;
			rows = parent.settings.rows;

			angle = RotateAngle.Deg0;
			direction = RotateDirection.ClockWise;
		}

		#endregion

        #region Property

        public int Range
        {
            get { return range; }
            set { range = value; }
        }

        public int XPosition
        {
            get { return xPosition; }
            set { xPosition = value; }
        }

        public int YPosition
        {
            get { return yPosition; }
            set { yPosition = value; }
        }

        public int GetAngle()
        {
            int returnValue;
            if (angle == RotateAngle.Deg0)
            {
                returnValue = 0;
                return returnValue;
            }
            if (angle == RotateAngle.Deg90)
            {
                returnValue = 1;
                return returnValue;
            }
            if (angle == RotateAngle.Deg180)
            {
                returnValue = 2;
                return returnValue;
            }
            return 3;
        }

        public void SetAngle(int angleValue)
        {
            if (angleValue == 0)
            {
                angle = RotateAngle.Deg0;               
            }
            if (angleValue == 1)
            {
                angle = RotateAngle.Deg90; 
            }
            if (angleValue == 2)
            {
                angle = RotateAngle.Deg180; 
            }
            if (angleValue == 3)
            {
                angle = RotateAngle.Deg270; 
            }
        }
	
        #endregion

		#region Virtual Methods

        /// <summary>
        /// Gets the indexes of the SingleSquare objects the figure has currently occupied.
        /// </summary>
        /// <returns></returns>
		protected virtual ArrayList GetRectsIndexes()
		{
			return null;
		}

        internal virtual void DrawPreview(Graphics g)
		{
		}

		#endregion

		#region Internal Methods

       	internal void Move(MoveDirection dir)
		{
			if(!CanMove(dir))
			{
				//if we tried to move figure down and we failed, so we need new figure
				if(dir == MoveDirection.Down)
					parent.newFigure = true;
				return;
			}
			//first clear previous location of the figure
			ClearFigure();
			switch(dir)
			{
				case MoveDirection.Left:
					xPosition -= 1;
					break;
				case MoveDirection.Right:
					xPosition += 1;
					break;
				case MoveDirection.Down:
					yPosition += 1;
					break;
				case MoveDirection.Rotate:
					ChangeRotateAngle();
					break;
			}
			//draw the figure at the new location
			DrawFigure();

			//refresh the tetris grid
			parent.SmartRefresh();
		}
		
		internal bool CanDraw()
		{
			//get the indexes of the figure and if twe have at least one which is filled
			//return false
			foreach(int i in GetRectsIndexes())
			{
				if(parent.squares[i].filled)
					return false;
			}

			return true;
		}


		#endregion		

		#region Drawing Methods

        internal void DrawFigure()
		{
			//get the indexes of the squares this figure occupies
			foreach(int index in GetRectsIndexes())
			{
				//add the rect in the invalid rects of the parent grid
				parent.invalidRects.Add(parent.squares[index]);
				//set the color for the square
				parent.squares[index].color = color;
				//set it to 'filled'
				parent.squares[index].filled = true;
			}
		}

		internal void DrawPreviewSquare(Rectangle r, Graphics g, Color c)
		{					
			r.Width -= 2;
			r.Height -= 2;

			g.FillRectangle(new SolidBrush(c),r);
			g.DrawLine(new Pen(parent.settings.lightBorder),r.Left,r.Bottom,r.Left,r.Top);
			g.DrawLine(new Pen(parent.settings.lightBorder),r.Left,r.Top,r.Right,r.Top);
			g.DrawLine(new Pen(parent.settings.darkBorder),r.Right,r.Top,r.Right,r.Bottom);
			g.DrawLine(new Pen(parent.settings.darkBorder),r.Right,r.Bottom,r.Left,r.Bottom);			
		}

		internal void ClearFigure()
		{
			//get the indexes of the squares thid figure occupies
			foreach(int index in GetRectsIndexes())
			{
				//add the square to the parent's invalid rects
				parent.invalidRects.Add(parent.squares[index]);
				//drop the flag 'filled'
				parent.squares[index].filled = false;
			}
		}

		#endregion

		#region Private Methods

        /// <summary>
        /// changes the rotation angle according to the rotate direction
        /// </summary>
		private void ChangeRotateAngle()
		{
			switch(angle)
			{
				case RotateAngle.Deg0:
					switch(direction)
					{
						case RotateDirection.ClockWise:
							angle = RotateAngle.Deg90;
							break;
						case RotateDirection.AntiClockWise:
							angle = RotateAngle.Deg270;
							break;
					}
					break;
				case RotateAngle.Deg90:
					switch(direction)
					{
						case RotateDirection.ClockWise:
							angle = RotateAngle.Deg180;
							break;
						case RotateDirection.AntiClockWise:
							angle = RotateAngle.Deg0;
							break;
					}
					break;
				case RotateAngle.Deg180:
					switch(direction)
					{
						case RotateDirection.ClockWise:
							angle = RotateAngle.Deg270;
							break;
						case RotateDirection.AntiClockWise:
							angle = RotateAngle.Deg90;
							break;
					}
					break;
				case RotateAngle.Deg270:
					switch(direction)
					{
						case RotateDirection.ClockWise:
							angle = RotateAngle.Deg0;
							break;
						case RotateDirection.AntiClockWise:
							angle = RotateAngle.Deg180;
							break;
					}
					break;
			}
		}

		private ArrayList GetDifferentIndexes(ArrayList oldIndexes, ArrayList newIndexes)
		{
			//the different indexes
			ArrayList different = new ArrayList();
			foreach(int i in newIndexes)
			{
				if(oldIndexes.Contains(i))
					continue;
				different.Add(i);
			}

			return different;
		}

		private bool CanMove(MoveDirection dir)
		{
			ArrayList oldIndexes = GetRectsIndexes();
			ArrayList newIndexes = new ArrayList();

            switch(dir)
			{
				case MoveDirection.Down:
					//if we have reached the end of the rows - do nothing
					if(yPosition + height == rows)
						return false;
					//perform fake offset
					yPosition += 1;
					//get the indexes with the new offset
					newIndexes = GetRectsIndexes();
					//restore previous position
					yPosition -= 1;
					break;
				case MoveDirection.Left:
					//if we are at the left side of the grid - do nothing
					if(xPosition == 0)
						return false;
					//perform fake offset
					xPosition -= 1;
					//get the indexes with the new offset
					newIndexes = GetRectsIndexes();
					//restore previous location
					xPosition += 1;
					break;
				case MoveDirection.Right:
					//if we are at the right side of the grid - do nothing
					if(xPosition + width == columns)
						return false;
					xPosition += 1;
					newIndexes = GetRectsIndexes();
					xPosition -= 1;
					break;
				case MoveDirection.Rotate:
					RotateAngle oldAngle = angle;
					ChangeRotateAngle();
					newIndexes = GetRectsIndexes();
					angle = oldAngle;
					//do not allow rotating if we are going to exceed the bounds of the grid
					if(yPosition + height > rows || xPosition + width > columns)
						return false;
					break;
			}

            //get the different indexes
			ArrayList different = GetDifferentIndexes(oldIndexes, newIndexes);

			foreach(int i in different)
			{
				//if we have at least one filled square in the different indexes, so we cannot
				//move the figure in the desired location
				if(parent.squares[i].filled)
					return false;
			}

            //no other conditions, so return true
			return true;
		}

		#endregion

		#region Fields

		internal int xPosition;
		internal int yPosition;
		internal int columns;
		internal int rows;
        internal int range;
		internal TetrisGrid parent;
		internal Color color;

		internal int width;
		internal int height;
		internal RotateAngle angle;
		internal RotateDirection direction;

		#endregion
	}
}

⌨️ 快捷键说明

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