C#游戏开发之实现俄罗斯方块游戏

作者:芝麻粒儿 时间:2022-11-24 11:12:31 

实践过程

效果

C#游戏开发之实现俄罗斯方块游戏

代码

public partial class Form1 : Form
{
   public Form1()
   {
       InitializeComponent();
   }

Russia MyRussia = new Russia();//实例化Russia类,用于操作游戏
   Russia TemRussia = new Russia();//实例化Russia类,用于生成下一个方块样式
   public static int CakeNO = 0;//记录下一个方块样式的标识
   public static bool become = false;//判断是否生成下一个方块的样式
   public static bool isbegin = false;//判断当前游戏是否开始
   public bool ispause = true;//判断是否暂停游戏
   public Timer timer = new Timer();

private void button1_Click(object sender, EventArgs e)
   {
       MyRussia.ConvertorClear();//清空整个控件
       MyRussia.firstPoi = new Point(140, 20);//设置方块的起始位置
       label3.Text = "0";//显示去除的行数
       label4.Text = "0";//显示分数
       MyRussia.Label_Linage = label3;//将label3控件加载到Russia类中
       MyRussia.Label_Fraction = label4;//将label4控件加载到Russia类中
       timer1.Interval = 500;//下移的速度
       timer1.Enabled = false;//停止计时
       timer1.Enabled = true;//开始计时
       Random rand = new Random();//实例化Random
       CakeNO = rand.Next(1, 8);//获取随机数
       MyRussia.CakeMode(CakeNO);//设置方块的样式
       MyRussia.Protract(panel1);//绘制组合方块
       beforehand();//生成下一个方块的样式
       MyRussia.PlaceInitialization();//初始化Random类中的信息
       isbegin = true;//判断是否开始
       ispause = true;
       MyRussia.timer = timer1;

button2.Text = "暂停";
       ispause = true;
       textBox1.Focus();//获取焦点
   }

/// <summary>
   /// 生成下一个方块的样式
   /// </summary>
   public void beforehand()
   {
       Graphics P3 = panel3.CreateGraphics();
       P3.FillRectangle(new SolidBrush(Color.Black), 0, 0, panel3.Width, panel3.Height);
       Random rand = new Random();//实例化Random
       CakeNO = rand.Next(1, 8);//获取随机数
       TemRussia.firstPoi = new Point(50, 30);//设置方块的起始位置
       TemRussia.CakeMode(CakeNO);//设置方块的样式
       TemRussia.Protract(panel3);//绘制组合方块
   }

private void Form1_KeyDown(object sender, KeyEventArgs e)
   {
       if (!isbegin)//如果没有开始游戏
           return;
       if (!ispause)//如果游戏暂停
           return;
       if (e.KeyCode == Keys.Up)//如果当前按下的是↑键
           MyRussia.MyConvertorMode();//变换当前方块的样式
       if (e.KeyCode == Keys.Down)//如果当前按下的是↓键
       {
           timer1.Interval = 300;//增加下移的速度
           MyRussia.ConvertorMove(0);//方块下移
       }
       if (e.KeyCode == Keys.Left)//如果当前按下的是←键
           MyRussia.ConvertorMove(1);//方块左移
       if (e.KeyCode == Keys.Right)//如果当前按下的是→键
           MyRussia.ConvertorMove(2);//方块右移
   }

private void timer1_Tick(object sender, EventArgs e)
   {
       MyRussia.ConvertorMove(0);//方块下移
       if (become)//如果显示新的方块
       {
           beforehand();//生成下一个方块
           become = false;
       }
       textBox1.Focus();//获取焦点
   }

private void Form1_KeyUp(object sender, KeyEventArgs e)
   {
       if (!isbegin)//如果游戏没有开始
           return;
       if (!ispause)//如果暂停游戏
           return;
       if (e.KeyCode == Keys.Down)//如果当前松开的是↓键
       {
           timer1.Interval = 500;//恢复下移的速度
       }
       textBox1.Focus();//获取焦点
   }

private void button2_Click(object sender, EventArgs e)
   {
       if (timer1.Enabled == true)
       {
           timer1.Stop();//暂停
           button2.Text = "继续";
           ispause = false;
           textBox1.Focus();//获取焦点
       }
       else
       {
           timer1.Start();//继续
           button2.Text = "暂停";
           ispause = true;
           textBox1.Focus();//获取焦点
       }
   }

private void panel1_Paint(object sender, PaintEventArgs e)
   {
       if (isbegin)//如是游戏开始
       {
           //重绘背景上的方块
           for (int i = 0; i <= (panel1.Width / 20 - 1); i++)
           {
               for (int j = 0; j <= (panel1.Height / 20 - 1); j++)
               {
                   Rectangle rect = new Rectangle(i * 20 + 1, j * 20 + 1, 19, 19);//获取各方块的绘制区域
                   e.Graphics.FillRectangle(new SolidBrush(Russia.PlaceColor[i, j]), rect);//绘制方块
               }
           }
       }
   }

private void panel3_Paint(object sender, PaintEventArgs e)
   {
       if (isbegin)//如果游戏开始
       {
           TemRussia.firstPoi = new Point(50, 30);//设置方块的起始位置
           TemRussia.CakeMode(CakeNO);//设置方块的样式
           TemRussia.Protract(panel3);//绘制组合方块
       }
   }
}
partial class Form1
{
   /// <summary>
   /// 必需的设计器变量。
   /// </summary>
   private System.ComponentModel.IContainer components = null;

/// <summary>
   /// 清理所有正在使用的资源。
   /// </summary>
   /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
   protected override void Dispose(bool disposing)
   {
       if (disposing && (components != null))
       {
           components.Dispose();
       }
       base.Dispose(disposing);
   }

#region Windows 窗体设计器生成的代码

/// <summary>
   /// 设计器支持所需的方法 - 不要
   /// 使用代码编辑器修改此方法的内容。
   /// </summary>
   private void InitializeComponent()
   {
       this.components = new System.ComponentModel.Container();
       this.panel1 = new System.Windows.Forms.Panel();
       this.button1 = new System.Windows.Forms.Button();
       this.textBox1 = new System.Windows.Forms.TextBox();
       this.timer1 = new System.Windows.Forms.Timer(this.components);
       this.button2 = new System.Windows.Forms.Button();
       this.panel2 = new System.Windows.Forms.Panel();
       this.panel3 = new System.Windows.Forms.Panel();
       this.label1 = new System.Windows.Forms.Label();
       this.label2 = new System.Windows.Forms.Label();
       this.label3 = new System.Windows.Forms.Label();
       this.label4 = new System.Windows.Forms.Label();
       this.panel2.SuspendLayout();
       this.SuspendLayout();
       //
       // panel1
       //
       this.panel1.BackColor = System.Drawing.SystemColors.WindowText;
       this.panel1.Location = new System.Drawing.Point(4, 5);
       this.panel1.Name = "panel1";
       this.panel1.Size = new System.Drawing.Size(281, 401);
       this.panel1.TabIndex = 0;
       this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
       //
       // button1
       //
       this.button1.Location = new System.Drawing.Point(291, 341);
       this.button1.Name = "button1";
       this.button1.Size = new System.Drawing.Size(75, 23);
       this.button1.TabIndex = 1;
       this.button1.Text = "开始";
       this.button1.UseVisualStyleBackColor = true;
       this.button1.Click += new System.EventHandler(this.button1_Click);
       //
       // textBox1
       //
       this.textBox1.Location = new System.Drawing.Point(291, 480);
       this.textBox1.Name = "textBox1";
       this.textBox1.Size = new System.Drawing.Size(10, 21);
       this.textBox1.TabIndex = 2;
       this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
       this.textBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
       //
       // timer1
       //
       this.timer1.Interval = 300;
       this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
       //
       // button2
       //
       this.button2.Location = new System.Drawing.Point(291, 370);
       this.button2.Name = "button2";
       this.button2.Size = new System.Drawing.Size(75, 23);
       this.button2.TabIndex = 3;
       this.button2.Text = "暂停";
       this.button2.UseVisualStyleBackColor = true;
       this.button2.Click += new System.EventHandler(this.button2_Click);
       //
       // panel2
       //
       this.panel2.BackColor = System.Drawing.Color.Black;
       this.panel2.Controls.Add(this.label4);
       this.panel2.Controls.Add(this.label3);
       this.panel2.Controls.Add(this.label2);
       this.panel2.Controls.Add(this.label1);
       this.panel2.Controls.Add(this.panel3);
       this.panel2.Location = new System.Drawing.Point(291, 5);
       this.panel2.Name = "panel2";
       this.panel2.Size = new System.Drawing.Size(120, 308);
       this.panel2.TabIndex = 4;
       //
       // panel3
       //
       this.panel3.Location = new System.Drawing.Point(10, 10);
       this.panel3.Name = "panel3";
       this.panel3.Size = new System.Drawing.Size(100, 100);
       this.panel3.TabIndex = 0;
       this.panel3.Paint += new System.Windows.Forms.PaintEventHandler(this.panel3_Paint);
       //
       // label1
       //
       this.label1.AutoSize = true;
       this.label1.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
       this.label1.ForeColor = System.Drawing.SystemColors.Window;
       this.label1.Location = new System.Drawing.Point(4, 148);
       this.label1.Name = "label1";
       this.label1.Size = new System.Drawing.Size(59, 16);
       this.label1.TabIndex = 1;
       this.label1.Text = "行数:";
       //
       // label2
       //
       this.label2.AutoSize = true;
       this.label2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
       this.label2.ForeColor = System.Drawing.Color.White;
       this.label2.Location = new System.Drawing.Point(4, 193);
       this.label2.Name = "label2";
       this.label2.Size = new System.Drawing.Size(59, 16);
       this.label2.TabIndex = 2;
       this.label2.Text = "分数:";
       //
       // label3
       //
       this.label3.AutoSize = true;
       this.label3.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
       this.label3.ForeColor = System.Drawing.Color.White;
       this.label3.Location = new System.Drawing.Point(48, 150);
       this.label3.Name = "label3";
       this.label3.Size = new System.Drawing.Size(15, 14);
       this.label3.TabIndex = 3;
       this.label3.Text = "0";
       //
       // label4
       //
       this.label4.AutoSize = true;
       this.label4.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
       this.label4.ForeColor = System.Drawing.Color.White;
       this.label4.Location = new System.Drawing.Point(48, 195);
       this.label4.Name = "label4";
       this.label4.Size = new System.Drawing.Size(15, 14);
       this.label4.TabIndex = 4;
       this.label4.Text = "0";
       //
       // Form1
       //
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.ClientSize = new System.Drawing.Size(415, 411);
       this.Controls.Add(this.panel2);
       this.Controls.Add(this.button2);
       this.Controls.Add(this.textBox1);
       this.Controls.Add(this.button1);
       this.Controls.Add(this.panel1);
       this.MaximizeBox = false;
       this.Name = "Form1";
       this.Text = "俄罗斯方块";
       this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
       this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
       this.panel2.ResumeLayout(false);
       this.panel2.PerformLayout();
       this.ResumeLayout(false);
       this.PerformLayout();

}

#endregion

private System.Windows.Forms.Panel panel1;
   private System.Windows.Forms.Button button1;
   private System.Windows.Forms.TextBox textBox1;
   private System.Windows.Forms.Timer timer1;
   private System.Windows.Forms.Button button2;
   private System.Windows.Forms.Panel panel2;
   private System.Windows.Forms.Panel panel3;
   private System.Windows.Forms.Label label3;
   private System.Windows.Forms.Label label2;
   private System.Windows.Forms.Label label1;
   private System.Windows.Forms.Label label4;
}
class Russia
{
   public Point firstPoi = new Point(140, 20);//定义方块的起始位置
   public static Color[,] PlaceColor;//记录方块的位置
   public static bool[,] Place;//记录方块的位置
   public static int conWidth = 0;//记录列数
   public static int conHeight = 0;//记录行数
   public static int maxY = 0;//方块在行中的最小高度
   public static int conMax = 0;//方块落下后的最大位置
   public static int conMin = 0;//方块落下后的最小位置
   bool[] tem_Array = { false, false, false, false };//记录方块组中那一块所在行中已满
   Color ConColor = Color.Coral;
   Point[] ArryPoi = new Point[4];//方块的数组
   Point[] Arryfront = new Point[4];//前一个方块的数组
   int Cake = 20;//定义方块的大小
   int Convertor = 0;//变换器
   Control Mycontrol = new Control();//实例化Control
   public Label Label_Linage = new Label();//实例化Label,用于显示去除的行数
   public Label Label_Fraction = new Label();//实例化Label,用于显示分数
   public static int[] ArrayCent = new int[] { 2, 5, 9, 15 };//记录加分情况
   public Timer timer = new Timer();

/// <summary>
   /// 设置方块的样式
   /// </summary>
   /// <param n="int">标识,方块的样式</param>
   public void CakeMode(int n)
   {
       ArryPoi[0] = firstPoi;//记录方块的起始位置
       switch (n)//根据标识设置方块的样式
       {
           case 1://组合“L”方块
               {
                   ArryPoi[1] = new Point(firstPoi.X, firstPoi.Y - Cake);//设置第二块方块的位置
                   ArryPoi[2] = new Point(firstPoi.X, firstPoi.Y + Cake);//设置第三块方块的位置
                   ArryPoi[3] = new Point(firstPoi.X + Cake, firstPoi.Y + Cake);//设置第四块方块的位置
                   ConColor = Color.Fuchsia;//设置当前方块的颜色
                   Convertor = 2;//记录方块的变换样式
                   break;
               }
           case 2://组合“Z”方块
               {
                   ArryPoi[1] = new Point(firstPoi.X, firstPoi.Y - Cake);
                   ArryPoi[2] = new Point(firstPoi.X - Cake, firstPoi.Y - Cake);
                   ArryPoi[3] = new Point(firstPoi.X + Cake, firstPoi.Y);
                   ConColor = Color.Yellow;
                   Convertor = 6;
                   break;
               }
           case 3://组合倒“L”方块
               {
                   ArryPoi[1] = new Point(firstPoi.X, firstPoi.Y - Cake);
                   ArryPoi[2] = new Point(firstPoi.X, firstPoi.Y + Cake);
                   ArryPoi[3] = new Point(firstPoi.X - Cake, firstPoi.Y + Cake);
                   ConColor = Color.CornflowerBlue;
                   Convertor = 8;
                   break;
               }
           case 4://组合倒“Z”方块
               {
                   ArryPoi[1] = new Point(firstPoi.X, firstPoi.Y - Cake);
                   ArryPoi[2] = new Point(firstPoi.X + Cake, firstPoi.Y - Cake);
                   ArryPoi[3] = new Point(firstPoi.X - Cake, firstPoi.Y);
                   ConColor = Color.Blue;
                   Convertor = 12;
                   break;
               }
           case 5://组合“T”方块
               {
                   ArryPoi[1] = new Point(firstPoi.X, firstPoi.Y - Cake);
                   ArryPoi[2] = new Point(firstPoi.X + Cake, firstPoi.Y - Cake);
                   ArryPoi[3] = new Point(firstPoi.X - Cake, firstPoi.Y - Cake);
                   ConColor = Color.Silver;
                   Convertor = 14;
                   break;
               }
           case 6://组合“一”方块
               {
                   ArryPoi[1] = new Point(firstPoi.X + Cake, firstPoi.Y);
                   ArryPoi[2] = new Point(firstPoi.X - Cake, firstPoi.Y);
                   ArryPoi[3] = new Point(firstPoi.X - Cake*2, firstPoi.Y);
                   ConColor = Color.Red;
                   Convertor = 18;
                   break;
               }
           case 7://组合“田”方块
               {
                   ArryPoi[1] = new Point(firstPoi.X - Cake, firstPoi.Y);
                   ArryPoi[2] = new Point(firstPoi.X - Cake, firstPoi.Y - Cake);
                   ArryPoi[3] = new Point(firstPoi.X, firstPoi.Y - Cake);
                   ConColor = Color.LightGreen;
                   Convertor = 19;
                   break;
               }
       }
   }

/// <summary>
   /// 清空游戏背景
   /// </summary>
   public void ConvertorClear()
   {
       if (Mycontrol != null)//如要已载入背景控件
       {
           Graphics g = Mycontrol.CreateGraphics();//创建背景控件的Graphics类
           Rectangle rect = new Rectangle(0, 0, Mycontrol.Width, Mycontrol.Height);//获取背景的区域
           MyPaint(g, new SolidBrush(Color.Black), rect);//用背景色填充背景
       }
   }

/// <summary>
   /// 清空当前方块的区域
   /// </summary>
   public void ConvertorDelete()
   {
       Graphics g = Mycontrol.CreateGraphics();//创建背景控件的Graphics类
       for (int i = 0; i < ArryPoi.Length; i++)//遍历方块的各个子方块
       {
           Rectangle rect = new Rectangle(ArryPoi[i].X, ArryPoi[i].Y, 20, 20);//获取各子方块的区域
           MyPaint(g, new SolidBrush(Color.Black), rect);//用背景色填充背景
       }
   }

/// <summary>
   /// 变换当前方块的样式
   /// </summary>
   public void MyConvertorMode()
   {
       ConvertorDelete();//清空当前方块的区域
       ConvertorMode(Convertor);//设置方块的变换样式
       Protract(Mycontrol);//绘制变换后的组合方块
   }

/// <summary>
   /// 设置方块的变换样式
   /// </summary>
   /// <param n="int">标识,判断变换的样式</param>
   public void ConvertorMode(int n)
   {
       Point[] tem_ArrayPoi = new Point[4];//定义一个临时数组
       Point tem_Poi = firstPoi;//获取方块的起始位置
       int tem_n = n;//记录方块的下一个变换样式
       //将当前方块的位置存入到临时数组中
       for (int i = 0; i < tem_ArrayPoi.Length; i++)
           tem_ArrayPoi[i] = ArryPoi[i];
       switch (n)//根据标识变换方块的样式
       {
           case 1://设置“L”方块的起始样式
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X + Cake, tem_Poi.Y + Cake);
                   tem_n = 2;//记录变换样式的标志
                   break;
               }
           case 2://“L”方块向旋转的样式
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X + Cake, tem_Poi.Y - Cake);
                   tem_n = 3;
                   break;
               }
           case 3://“L”方块向旋转的样式
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X - Cake, tem_Poi.Y - Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_n = 4;
                   break;
               }
           case 4://“L”方块向旋转的样式
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X - Cake, tem_Poi.Y + Cake);
                   tem_n = 1;//返回方块的起始样式
                   break;
               }
           case 5://Z
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X - Cake, tem_Poi.Y - Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_n = 6;
                   break;
               }
           case 6:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X + Cake, tem_Poi.Y - Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_n = 5;
                   break;
               }
           case 7://倒L
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X - Cake, tem_Poi.Y + Cake);
                   tem_n = 8;
                   break;
               }
           case 8:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X + Cake, tem_Poi.Y + Cake);
                   tem_n = 9;
                   break;
               }
           case 9:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X + Cake, tem_Poi.Y - Cake);
                   tem_n = 10;
                   break;
               }
           case 10:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X - Cake, tem_Poi.Y - Cake);
                   tem_n = 7;
                   break;
               }
           case 11://倒Z
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X + Cake, tem_Poi.Y - Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_n = 12;
                   break;
               }
           case 12:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X - Cake, tem_Poi.Y - Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_n = 11;
                   break;
               }
           case 13://T
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X + Cake, tem_Poi.Y - Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X - Cake, tem_Poi.Y - Cake);
                   tem_n = 14;
                   break;
               }
           case 14:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_n = 15;
                   break;
               }
           case 15:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_n = 16;
                   break;
               }
           case 16:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_n = 13;
                   break;
               }
           case 17://一
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X + Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X - Cake * 2, tem_Poi.Y);
                   tem_n = 18;
                   break;
               }
           case 18:
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X, tem_Poi.Y + Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X, tem_Poi.Y + Cake * 2);
                   tem_n = 17;
                   break;
               }
           case 19://田
               {
                   tem_ArrayPoi[1] = new Point(tem_Poi.X - Cake, tem_Poi.Y);
                   tem_ArrayPoi[2] = new Point(tem_Poi.X - Cake, tem_Poi.Y - Cake);
                   tem_ArrayPoi[3] = new Point(tem_Poi.X, tem_Poi.Y - Cake);
                   tem_n = 19;
                   break;
               }
       }
       bool tem_bool = true;//判断方块是否可变
       //遍历方块的各个子方块
       for (int i = 0; i < tem_ArrayPoi.Length; i++)
       {
           if (tem_ArrayPoi[i].X / 20 < 0)//变换后是否超出左边界
           {
               tem_bool = false;//不变换
               break;
           }
           if (tem_ArrayPoi[i].X / 20 >= conWidth)//变换后是否超出右边界
           {
               tem_bool = false;
               break;
           }
           if (tem_ArrayPoi[i].Y / 20 >= conHeight)//变换后是否超出下边界
           {
               tem_bool = false;
               break;
           }
           if (Place[tem_ArrayPoi[i].X / 20, tem_ArrayPoi[i].Y / 20])//变换后是否与其他方块重叠
           {
               tem_bool = false;
               break;
           }
       }
       if (tem_bool)//如果当前方块可以变换
       {
           //改变当前方块的样式
           for (int i = 0; i < tem_ArrayPoi.Length; i++)
               ArryPoi[i] = tem_ArrayPoi[i];
           firstPoi = tem_Poi;//获取当前方块的起始位置
           Convertor = tem_n;//获取方块下一次的变换样式
       }
   }

/// <summary>
   /// 绘制组合方块
   /// </summary>
   /// <param control="Control">控件</param>
   public void Protract(Control control)
   {
       Mycontrol = control;
       Graphics g = control.CreateGraphics();//创建背景控件的Graphics类
       //绘制方块的各个子方块
       for (int i = 0; i < ArryPoi.Length; i++)
       {
           Rectangle rect = new Rectangle(ArryPoi[i].X + 1, ArryPoi[i].Y + 1, 19, 19);//获取子方块的区域
           MyPaint(g, new SolidBrush(ConColor), rect);//绘制子方块
       }
   }

/// <summary>
   /// 对方块的单个块进行绘制
   /// </summary>
   /// <param g="Graphics">封装一个绘图的类对象</param>
   /// <param SolidB="SolidBrush">画刷</param>
   /// <param rect="Rectangle">绘制区域</param>
   public void MyPaint(Graphics g, SolidBrush SolidB, Rectangle rect)
   {
       g.FillRectangle(SolidB, rect);//填充一个矩形
   }

/// <summary>
   /// 方块移动
   /// </summary>
   /// <param n="int">标识,对左右下进行判断</param>
   public void ConvertorMove(int n)
   {
       //记录方块移动前的位置
       for (int i = 0; i < Arryfront.Length; i++)
           Arryfront[i] = ArryPoi[i];
       switch (n)//方块的移动方向
       {
           case 0://下移
               {
                   //遍历方块中的子方块
                   for (int i = 0; i < Arryfront.Length; i++)
                       Arryfront[i] = new Point(Arryfront[i].X, Arryfront[i].Y + Cake);//使各子方块下移一个方块位
                   break;
               }
           case 1://左移
               {
                   for (int i = 0; i < Arryfront.Length; i++)
                       Arryfront[i] = new Point(Arryfront[i].X - Cake, Arryfront[i].Y);
                   break;
               }
           case 2://右移
               {
                   for (int i = 0; i < Arryfront.Length; i++)
                       Arryfront[i] = new Point(Arryfront[i].X + Cake, Arryfront[i].Y);

break;
               }
       }

bool tem_bool = MoveStop(n);//记录方块移动后是否出边界
       if (tem_bool)//如果没有出边界
       {
           ConvertorDelete();//清空当前方块的区域
           //获取移动后方块的位置
           for (int i = 0; i < Arryfront.Length; i++)
               ArryPoi[i] = Arryfront[i];
           firstPoi = ArryPoi[0];//记录方块的起始位置
           Protract(Mycontrol);//绘制移动后方块
       }
       else//如果方块到达底部
       {
           if (!tem_bool && n == 0)//如果当前方块是下移
           {
               conMax = 0;//记录方块落下后的顶端位置
               conMin = Mycontrol.Height;//记录方块落下后的底端位置
               //遍历方块的各个子方块
               for (int i = 0; i < ArryPoi.Length; i++)
               {
                   if (ArryPoi[i].Y < maxY)//记录方块的顶端位置
                       maxY = ArryPoi[i].Y;
                   Place[ArryPoi[i].X / 20, ArryPoi[i].Y / 20] = true;//记录指定的位置已存在方块
                   PlaceColor[ArryPoi[i].X / 20, ArryPoi[i].Y / 20] = ConColor;//记录方块的颜芭
                   if (ArryPoi[i].Y > conMax)//记录方块的顶端位置
                       conMax = ArryPoi[i].Y;
                   if (ArryPoi[i].Y < conMin)//记录方块的底端位置
                       conMin = ArryPoi[i].Y;
               }
               if (firstPoi.X == 140 && firstPoi.Y == 20)
               {
                   timer.Stop();
                   Form1.isbegin = false;
                   return;
               }

Random rand = new Random();//实例化Random
               int CakeNO = rand.Next(1, 8);//获取随机数
               firstPoi = new Point(140, 20);//设置方块的起始位置
               CakeMode(Form1.CakeNO);//设置方块的样式
               Protract(Mycontrol);//绘制组合方块
               RefurbishRow(conMax,conMin);//去除已填满的行
               Form1.become = true;//标识,判断可以生成下一个方块
           }
       }
   }

/// <summary>
   /// 去除已添满的行
   /// </summary>
   public void RefurbishRow(int Max,int Min)
   {
       Graphics g = Mycontrol.CreateGraphics();//创建背景控件的Graphics类
       int tem_max = Max / 20;//获取方块的最大位置在多少行
       int tem_min = Min / 20;//获取方块的最小位置在多少行
       bool tem_bool = false;
       //初始化记录刷新行的数组
       for (int i = 0; i < tem_Array.Length; i++)
           tem_Array[i] = false;
       int tem_n = maxY;//记录最高行的位置
       for (int i = 0; i < 4; i++)//查找要刷新的行
       {
           if ((tem_min + i) > 19)//如果超出边界
               break;//退出本次操作
           tem_bool = false;
           //如果当前行中有空格
           for (int k = 0; k < conWidth; k++)
           {
               if (!Place[k, tem_min + i])//如果当前位置为空
               {
                   tem_bool = true;
                   break;
               }
           }
           if (!tem_bool)//如要当行为满行
           {
               tem_Array[i] = true;//记录为刷新行
           }
       }

int Progression = 0;//记录去除的几行
       if (tem_Array[0] == true || tem_Array[1] == true || tem_Array[2] == true || tem_Array[3] == true)//如果有刷新行
       {
           int Trow = 0;//记录最小行数
           for (int i = (tem_Array.Length - 1); i >= 0; i--)//遍历记录刷新行的数组
           {
               if (tem_Array[i])//如果是刷新行
               {
                   Trow = Min / 20 + i;//记录最小行数
                   //将刷新行到背景顶端的区域下移
                   for (int j = Trow; j >=1 ; j--)
                   {
                       for (int k = 0; k < conWidth; k++)
                       {
                           PlaceColor[k, j] = PlaceColor[k, j - 1];//记录方块的位置
                           Place[k, j] = Place[k, j - 1];//记录方块的位置
                       }
                   }
                   Min += 20;//方块的最小位置下移一个方块位
                   //将背景的顶端清空
                   for (int k = 0; k < conWidth; k++)
                   {
                       PlaceColor[k, 0] = Color.Black;//记录方块的位置
                       Place[k, 0] = false;//记录方块的位置
                   }
                   Progression += 1;//记录刷新的行数
               }
           }

//在背景中绘制刷新后的方块图案
           for (int i = 0; i < conWidth; i++)
           {
               for (int j = 0; j <= Max / 20; j++)
               {
                   Rectangle rect = new Rectangle(i * Cake + 1, j * Cake + 1, 19, 19);//获取各方块的区域
                   MyPaint(g, new SolidBrush(PlaceColor[i, j]), rect);//绘制已落下的方块
               }
           }
           //显示当前的刷新行数
           Label_Linage.Text = Convert.ToString(Convert.ToInt32(Label_Linage.Text) + Progression);
           //显示当前的得分情况
           Label_Fraction.Text = Convert.ToString(Convert.ToInt32(Label_Fraction.Text) + ArrayCent[Progression - 1]);
       }
   }

/// <summary>
   /// 对信息进行初始化
   /// </summary>
   public void PlaceInitialization()
   {
       conWidth=Mycontrol.Width / 20;//获取背景的总行数
       conHeight = Mycontrol.Height / 20;//获取背景的总列数
       Place = new bool[conWidth, conHeight];//定义记录各方块位置的数组
       PlaceColor = new Color[conWidth, conHeight];//定义记录各方块颜色的数组
       //对各方块的信息进行初始化
       for (int i = 0; i < conWidth; i++)
       {
           for (int j = 0; j < conHeight; j++)
           {
               Place[i, j] = false;//方块为空
               PlaceColor[i, j] = Color.Black;//与背景色相同
           }
       }
       maxY = conHeight * Cake;//记录方块的最大值
   }

/// <summary>
   /// 判断方块移动时是否出边界
   /// </summary>
   public bool MoveStop(int n)
   {
       bool tem_bool = true;
       int tem_width = 0;
       int tem_height = 0;
       switch (n)
       {
           case 0://下移
               {
                   //遍历方块中的各个子方块
                   for (int i = 0; i < Arryfront.Length; i++)
                   {
                       tem_width = Arryfront[i].X / 20;//获取方块的横向坐标值
                       tem_height = Arryfront[i].Y / 20;//获取方块的纵向坐标值
                       if (tem_height == conHeight || Place[tem_width, tem_height])//判断是否超出底边界,或是与其他方块重叠
                           tem_bool = false;//超出边界
                   }
                   break;
               }
           case 1://左移
               {
                   for (int i = 0; i < Arryfront.Length; i++)
                   {
                       tem_width = Arryfront[i].X / 20;
                       tem_height = Arryfront[i].Y / 20;
                       if (tem_width == -1 || Place[tem_width, tem_height])//判断是否超出左边界,或是与其他方块重叠
                           tem_bool = false;
                   }
                   break;
               }
           case 2://右移
               {
                   for (int i = 0; i < Arryfront.Length; i++)
                   {
                       tem_width = Arryfront[i].X / 20;
                       tem_height = Arryfront[i].Y / 20;
                       if (tem_width == conWidth || Place[tem_width, tem_height])//判断是否超出右边界,或是与其他方块重叠
                           tem_bool = false;
                   }
                   break;
               }
       }
       return tem_bool;
   }

}

来源:https://blog.csdn.net/qq_27489007/article/details/128474521

标签:C#,俄罗斯方块,游戏
0
投稿

猜你喜欢

  • Java原生序列化和反序列化代码实例

    2023-10-29 21:46:45
  • Android WebView实现网页滚动截图

    2022-12-12 12:13:03
  • 详解Java后端优雅验证参数合法性

    2021-09-06 16:07:22
  • C#线性渐变画刷LinearGradientBrush用法实例

    2022-01-21 05:29:43
  • C#泛型委托的用法实例分析

    2021-09-16 23:29:52
  • java面向对象编程类的内聚性分析

    2022-02-24 23:43:00
  • Android开发实现的计时器功能示例

    2023-09-04 07:33:33
  • java UDP实现一个聊天工具的示例代码

    2021-09-19 18:41:47
  • Springboot WebJar打包及使用实现流程解析

    2023-06-21 22:08:00
  • 阿里nacos+springboot+dubbo2.7.3统一处理异常的两种方式

    2022-12-05 03:50:25
  • Spring AOP底层源码详解

    2022-03-12 02:00:26
  • sqlite数据库的介绍与java操作sqlite的实例讲解

    2023-05-09 03:07:40
  • Java代码实现酒店管理系统

    2023-08-13 13:09:23
  • C#中Foreach循环遍历的本质与枚举器详解

    2022-08-04 05:31:12
  • prometheus监控springboot应用简单使用介绍详解

    2023-02-24 03:49:00
  • Flutter状态管理Bloc使用示例详解

    2023-08-24 09:09:10
  • java8 如何实现分组计算数量和计算总数

    2022-05-05 01:17:32
  • 详解C#获取特定进程CPU和内存使用率

    2022-06-23 03:06:42
  • Mybatis是这样防止sql注入的

    2022-05-30 02:05:16
  • Java 通过反射给实体类赋值操作

    2023-11-26 10:11:41
  • asp之家 软件编程 m.aspxhome.com