首页 > 代码库 > 俄罗斯方块

俄罗斯方块

俄罗斯方块大家都很熟悉的游戏,小时候就开始玩的,做为IT屌丝的我也想写一个俄罗斯方块的小游戏,于是去查质料怎么写,查出来的都是大神写的,很强大很牛逼,可是我是小白,看不懂,代码注释不见几个,没法子了,自己想呗,这情况也不是一次遇到,我很气愤,所以我自己写出来分享的东西一定要把注释写详细,让和我一样还是小白级别的IT屌丝的同道们少走弯路,同时也记下笔记。

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10 
 11 namespace ShapeUI
 12 {
 13     public partial class forShape : Form
 14     {
 15         public forShape()
 16         {
 17             InitializeComponent();
 18         }
 19         private void forShape_Load(object sender, EventArgs e)
 20         {
 21             lblGrade.Text = "0";//显示等级
 22             lblScore.Text = "0";//显示分数
 23             Helper.Speed = 550;
 24             tirShape.Interval = Helper.Speed;
 25             lblSpeed.Text = Helper.Speed.ToString();//显示速度
 26             forCue f = new forCue();//提示
 27             f.ShowDialog();//显示提示
 28         }
 29         private bool Stop(int key) //结束操作
 30         {
 31             bool b = true;
 32             foreach (Control c in gpbGame.Controls)
 33             {
 34                 if (c.Enabled)
 35                 {
 36                     int x = c.Location.X;
 37                     int y = c.Location.Y;
 38                     //判断是否撞墙
 39                     if (x >= gpbGame.Width - 20 && key == 68)
 40                     {
 41                         b = false;
 42                         break;
 43                     }
 44                     else if (x <= 0 && key == 65)
 45                     {
 46                         b = false;
 47                         break;
 48                     }
 49                     else if (y >= gpbGame.Height - 20 && key == 83)
 50                     {
 51                         b = false;
 52                         Enableds();//如果是下落操作碰到墙则固定形状
 53                         break;
 54                     }
 55                 }
 56             }
 57             return b;
 58         }
 59         public void Enableds()//固定
 60         {
 61             foreach (Control c in gpbGame.Controls)
 62             {
 63                 if (c.Enabled)
 64                 {
 65                     c.KeyDown -= buttons_KeyDown;//消除按钮事件
 66                     c.Enabled = false;
 67                     int Red = new Random().Next(1, 256);
 68                     int Green = new Random().Next(1, 256);
 69                     int Blue = (Red + Green > 400) ? 0 : 400 - Red - Green;
 70                     Blue = (Blue > 255) ? 255 : Blue;
 71                     //固定变换颜色
 72                     c.BackColor = Color.FromArgb(Red, Green, Blue);
 73                 }
 74                 //判断游戏结束
 75                 if (c.Location.Y >= gpbGame.Height && !c.Enabled)
 76                 {
 77                     tirShape.Stop();
 78                     MessageBox.Show("Game Over");
 79                     return;
 80                 }
 81             }
 82             GetShape();//生成新的形状
 83         }
 84         private void GetShape() //生成形状
 85         {
 86             Helper.Score(gpbGame, lblScore);//加分判断
 87             lblGrade.Text = Helper.Grade.ToString();//刷新等级
 88             tirShape.Interval = Helper.Speed;
 89             lblSpeed.Text = Helper.Speed.ToString();//刷新速度
 90             IShapes s = CreateShape.createShape(new Random().Next(1, 6));//获取形状
 91             foreach (Control c in s.Getbuttons())
 92             {
 93                 c.KeyDown += buttons_KeyDown;//添加事件
 94                 gpbGame.Controls.Add(c);
 95                 c.Focus();//获取焦点
 96             }
 97         }
 98         private void buttons_KeyDown(object sender, KeyEventArgs e)//键盘事件
 99         {
100             MoveShape(e.KeyValue);//移动判断
101         }
102         private bool Impacts(int x, int y, int key) //向下碰撞到方块
103         {
104             bool b = true;
105             foreach (Control c in gpbGame.Controls)
106             {
107                 if (c.Enabled)
108                 {
109                     //判断是否碰撞到方块
110                     if (c.Location.X == x && c.Location.Y == y)
111                     {
112                         if (key == 83)//如果是向下降落的操作便固定
113                             Enableds();
114                         b = false;
115                         break;
116                     }
117 
118                 }
119             }
120             return b;
121         }
122         private void MoveShape(int key)//移动位置
123         {
124             if (Stop(key))//是否碰撞
125             {
126                 //预计下一步将要发生的事情
127                 foreach (Control c in gpbGame.Controls)
128                 {
129                     if (!c.Enabled)
130                     {
131                         int x = c.Location.X;
132                         int y = c.Location.Y;
133                         if (key == 65)
134                             x += 20;
135                         else if (key == 68)
136                             x -= 20;
137                         else if (key == 87)
138                         {
139                             //ChangeShape();
140                         }
141                         else if (key == 83)
142                         {
143                             y -= 20;
144                         }
145                         if (!Impacts(x, y, key))//判断是否与方块碰撞,是则结束
146                             return;
147                     }
148                 }
149                 //如果预计通过则实施操作
150                 foreach (Control c in gpbGame.Controls)
151                 {
152                     if (c.Enabled)
153                     {
154                         int x = c.Location.X;
155                         int y = c.Location.Y;
156                         if (key == 65)
157                             x -= 20;
158                         else if (key == 68)
159                             x += 20;
160                         else if (key == 87)
161                         {
162                             Helper.ChangeShape(gpbGame);//变换
163                             return;//变换形状后结束方法,否则会导致循环变换
164                         }
165                         else if (key == 83)
166                         {
167                             y += 20;
168                         }
169                         c.Location = new Point(x, y);//移动操作
170                     }
171                 }
172             }
173         }
174         private void btnBegin_Click(object sender, EventArgs e)//开始游戏
175         {
176             if (btnBegin.Text == "游戏开始")
177             { 
178                 btnBegin.Text = "重新开始";
179             }
180             else
181             {
182                 btnBegin.Text = "游戏开始";
183             }
184             lblGrade.Text = "0";//初始化等级
185             lblScore.Text = "0";//初始化分数
186             Helper.Speed = 550;
187             tirShape.Interval = Helper.Speed;
188             lblSpeed.Text = Helper.Speed.ToString();//初始化速度
189             this.gpbGame.Controls.Clear();//初始化游戏窗口
190             GetShape();//生成形状
191             tirShape.Start();
192         }
193  
194         private void btnEnd_Click(object sender, EventArgs e)//游戏结束
195         {
196             tirShape.Stop();
197             Application.Exit();
198         }
199 
200         private void tirShape_Tick(object sender, EventArgs e)//计时器
201         {
202             MoveShape(83);//默认自动下降操作
203         }
204 
205         private void btnStop_Click(object sender, EventArgs e)//暂停游戏
206         {
207             if (tirShape.Enabled)
208             {
209                 tirShape.Stop();
210                 forStop f = new forStop();
211                 f.ShowDialog();//暂停中
212                 tirShape.Start();//暂停结束
213             }    
214         }
215     }
216 }
View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Drawing;
  4 using System.Linq;
  5 using System.Text;
  6 using System.Threading.Tasks;
  7 using System.Windows.Forms;
  8 
  9 namespace ShapeUI
 10 {
 11     public static class Helper
 12     {
 13         public static int Speed { get; set; }//速度
 14         public static int Grade { get; set; }//等级
 15         public static List<button> Getbuttons(int[,] points) //组成形状
 16         {
 17             List<button> bs = new List<button>();
 18             for (int i = 0; i < 4; i++)
 19             {
 20                 button b = new button();
 21                 b.Location = new System.Drawing.Point(points[0, i], points[1, i]);//初始化坐标
 22                 if (i == 1)
 23                 {
 24                     b.Tag = "point";//定义原点
 25                 }
 26                 else
 27                     b.Tag = "";
 28                 bs.Add(b);
 29             }
 30             return bs;
 31         }
 32         public static void Score(GroupBox gpbGame, Label lblScore)//得分
 33         {
 34             int length = gpbGame.Width / 20;
 35             for (int i = 0; i < length; i++)//没行都判断是否满足加分条件
 36             {
 37                 AddScore(i,gpbGame,lblScore);//加分操作
 38             }
 39         }
 40         public static void AddScore(int rowPage, GroupBox gpbGame,Label lblScore)
 41         {
 42             int count = 0;
 43             int length = gpbGame.Width / 20;//列数
 44             List<button> list = new List<button>();
 45             foreach (Control c in gpbGame.Controls)
 46             {
 47                 if (c is button && !c.Enabled && c.Location.Y == gpbGame.Height - 20 * rowPage)//判断是否为指定行的区域
 48                 {
 49                     count++;
 50                     list.Add(c as button);//要删除的控件
 51                 }
 52                 if (count >= length)
 53                 {
 54                     int score = Convert.ToInt32(lblScore.Text);
 55                     lblScore.Text = (score += 1).ToString();//刷新分数
 56                     if(score == 5)//分数等级
 57                     {
 58                         Grade = 1;
 59                         Speed = 550;
 60                     }else if(score == 15)
 61                     {
 62                         Grade = 2;
 63                         Speed = 450;
 64                     }
 65                     else if (score == 35)
 66                     {
 67                         Grade = 3;
 68                         Speed = 400;
 69                     }
 70                     else if (score == 80)
 71                     {
 72                         Grade = 4;
 73                         Speed = 350;
 74                     }
 75                     else if (score == 200)
 76                     {
 77                         Grade = 5;
 78                         Speed = 300;
 79                     }
 80                     foreach (button b in list)
 81                     {
 82                         b.Dispose();//引用类型会同步所有的地址
 83                     }
 84 
 85                     Subtract(count, rowPage,gpbGame);//位置下降
 86                     foreach (Control b in gpbGame.Controls)
 87                     {
 88                         if (b is button && !b.Enabled && b.Location.Y == gpbGame.Height - 20 * rowPage)
 89                         {
 90                             count--;
 91                             if (count == 0)//在次满足等分条件递归调用加分
 92                                 Score(gpbGame,lblScore);
 93                         }
 94                     }
 95                     return;
 96                 }
 97             }
 98         }
 99         public static void Subtract(int count, int rowPage, GroupBox gpbGame)//减行
100         {
101             foreach (Control bb in gpbGame.Controls)
102             {
103                 if (bb is button && !bb.Enabled && bb.Location.Y == gpbGame.Height - 20 * rowPage)
104                 {
105                     count--;//判断整行是否有控件
106                 }
107             }
108             foreach (Control b in gpbGame.Controls)
109             {
110                 //如果该行是空的则下降一行
111                 if (count == 13 && !b.Enabled && b.Location.Y <= gpbGame.Height - 20 * rowPage)
112                 {
113                     int y = b.Location.Y;
114                     b.Location = new Point(b.Location.X, y += 20);
115                 }
116             }
117         }
118         
119         public static void ChangeShape(GroupBox gpbGame)//变换位置
120         {
121             int pointx = 0;
122             int pointy = 0;
123             //先取到原点坐标
124             foreach (Control c in gpbGame.Controls)
125             {
126                 if (c.Enabled)//原点坐标为100,40
127                 {
128                     if (c.Tag.ToString() == "point")
129                     {
130                         pointx = c.Location.X;//得到原点坐标
131                         pointy = c.Location.Y;
132                         break;
133                     }
134                 }
135             }
136             
137             bool b = true;
138             foreach (Control c in gpbGame.Controls)
139             {
140                 if (c.Enabled)//原点坐标为第二个方块坐标
141                 {
142                     int x = c.Location.X - pointx;
143                     int y = -c.Location.Y + pointy;//得到相对坐标
144                     int X = y + pointx;
145                     int Y = x + pointy;//相对于原点的坐标
146                     //判断方块是否超出边界
147                     if (X >= gpbGame.Width || X < 0 || Y > gpbGame.Height || Y < 0)
148                     {
149                         b = false;
150                         c.BackColor = Color.Black;
151                         break;
152                     }
153                     //判断方块是否碰到方块
154                     foreach (Control cc in gpbGame.Controls)
155                     {
156                         if (!cc.Enabled)
157                         {
158                             if (X == cc.Location.X && Y == cc.Location.Y)
159                             {
160                                 b = false;
161                                 break;
162                             }
163                         }
164                     }
165                 }
166             }
167             if (b)//判断操作可行
168             {
169                 foreach (Control c in gpbGame.Controls)
170                 {
171                     if (c.Enabled)
172                     {
173                         int x = c.Location.X - pointx;
174                         int y = -c.Location.Y + pointy;
175                         c.Location = new Point(y + pointx, x + pointy);                    }
176                 }
177             }
178         }
179         
180     }
181 }
View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace ShapeUI
 8 {
 9     public class CreateShape
10     {
11         public static IShapes createShape(int shape)
12         {
13             IShapes s = null;
14             switch(shape)
15             {
16                 case 1:
17                     s = new Shape1();
18                     break;
19                 case 2:
20                     s = new Shape2();
21                     break;
22                 case 3:
23                     s = new Shape3();
24                     break;
25                 case 4:
26                     s = new Shape4();
27                     break;
28                 case 5:
29                     s = new Shape5();
30                     break;
31             }
32             return s;
33         }
34     }
35 }
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ShapeUI
{
    public interface IShapes
    {
        List<button> Getbuttons();
    }
}
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace ShapeUI
 8 {
 9     public class Shape1 : IShapes
10     {
11         //山字型
12         private int[,] points = new int[,] { {80,100,120,100 }, {40,40,40,20 } };//初始化形状坐标
13         public List<button> Getbuttons()//返回一个形状
14         {
15             return Helper.Getbuttons(points);
16         }
17     }
18 }
View Code

其它几个形状也都是一样的