俄罗斯方块大家都很熟悉的游戏,小时候就开始玩的,做为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 }
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 }
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 }
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 }
其它几个形状也都是一样的
原文:http://www.cnblogs.com/LiuZhen/p/3770055.html