C# 实现俄罗斯方块(附源码)_C#教程_俄罗斯方块2012

时间:2021年05月10日 01:08:15

概述

俄罗斯方块(Tetris)是一款由俄罗斯人阿列克谢・帕基特诺夫发明的休闲游戏,帕基特诺夫爱玩拼图,从拼图游戏里得到灵感,设计出了俄罗斯方块。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。本文简述如何通过C#来实现俄罗斯方块,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点

BackgroundWorker 在单独的线程上执行操作(主要执行比较耗时的操作)。Action .NetFramework自带的一个委托方法。TableLayoutPanel  表示一个面板,它可以在一个由行和列组成的网格中对其内容进行动态布局,本文主要用作俄罗斯方块的容器。

方块流程图

如下图所示,描述了俄罗斯方块的设计流程图

俄罗斯方块效果图

如下图所示:主要包括状态,得分,开始按钮,停止按钮,按键盘左右箭头移动等功能

核心代码

1. 定义方块的形状

如下所示:共7中形状

/// /// 俄罗斯方块的形状 /// public enum TetrisStyle {S = 0,Z = 1,L = 2,J = 3,I = 4,O = 5,T = 6 }

2. 定义移动的方向

如下所示:默认向下移动,同时可以左右移动

/// /// 俄罗斯方块移动方向 /// public enum TetrisDirection {UP = 0,//上,表示顺时针旋转DOWN = 1,//下,表示向下移动LEFT = 2,//左,表示往左移动RIGHT = 3, //表示向右移动DEFAULT=4 //默认动作 }

3. 俄罗斯方块元素如下所示,每一种形状都由四个方块组成,根据不同形状设置不同的位置

/// /// 俄罗斯方块元素/// public class TetrisElement{ /// /// 构造函数 /// /// public TetrisElement(TetrisStyle style) {this.style = style; } /// /// 构造函数 /// /// 形状 /// 内容 /// 位置 public TetrisElement(TetrisStyle style, Point[] content, Point location) {this.style = style;this.content = content;this.location = location; } /// /// 元素字母类型 /// public TetrisStyle style { get; set; } /// /// 内容 /// public Point[] content { get; set; } /// /// 元素位置 /// public Point location { get; set; } /// /// 位置改变 /// /// /// public void move(int x, int y) {this.location = new Point(x, y); } public Point[] getContent(TetrisStyle style) {//内容由四个点组成,顺序:先上后下,先左后右Point[] content = new Point[4];switch (style){ case TetrisStyle.I://I形状content[0] = new Point(0, 0);content[1] = new Point(0, 1);content[2] = new Point(0, 2);content[3] = new Point(0, 3);break; case TetrisStyle.J://J形状content[0] = new Point(1, 0);content[1] = new Point(1, 1);content[2] = new Point(1, 2);content[3] = new Point(0, 2);break; case TetrisStyle.L://L形状content[0] = new Point(0, 0);content[1] = new Point(0, 1);content[2] = new Point(0, 2);content[3] = new Point(1, 2);break; case TetrisStyle.O://O形状content[0] = new Point(0, 0); content[1] = new Point(1, 0);content[2] = new Point(0, 1); content[3] = new Point(1, 1); break;case TetrisStyle.S: //S形状 content[0] = new Point(2, 0); content[1] = new Point(1, 0);content[2] = new Point(1, 1); content[3] = new Point(0, 1);break;case TetrisStyle.T: //T形状 content[0] = new Point(0, 0);content[1] = new Point(1, 0);content[2] = new Point(2, 0); content[3] = new Point(1, 1); break;case TetrisStyle.Z: //Z形状content[0] = new Point(0, 0); content[1] = new Point(1, 0);content[2] = new Point(1, 1);content[3] = new Point(2, 1);break; default://默认Icontent[0] = new Point(0, 0);content[1] = new Point(0, 1);content[2] = new Point(0, 2);content[3] = new Point(0, 3);break;}return content; }}

4. 容器类如下所示:容器类主要是移动方块元素,并更新页面上的值

/// /// 俄罗斯方块容器 /// public class TetrisContainer {private int[,] tetris = new int[10, 20];//定义二维数组,表示坐标信息,默认值为0public Action onPartialChanged;//局部变更事件public Action onFullChanged;//元素全变更事件,即有整行被清除事件public Action onCompleted; //结束事件public int scorce = 0;/// /// 状态发生改变/// /// /// /// public TetrisElement change(TetrisElement element, TetrisDirection direction){ TetrisElement tmp=null; //判断不同的方向 switch (direction) {case TetrisDirection.DEFAULT: //如果可以向下移动 if (checkDefault(element)) {//向下移动一个元素element.move(element.location.X, element.location.Y + 1);tmp = element; } else {//如果不可以向下移动,则更新容器updateTetris(element);tmp = null; } break;case TetrisDirection.DOWN: break;case TetrisDirection.UP: break;case TetrisDirection.LEFT: if (checkLeft(element)){//判断是否可以向左移动//向下移动一个元素element.move(element.location.X-1, element.location.Y);tmp = element; } break;case TetrisDirection.RIGHT: if (checkRight(element)) {//判断是否可以右左移动//向下移动一个元素element.move(element.location.X+1, element.location.Y);tmp = element; } break; } //局部变更 if (onPartialChanged != null) {Point location = element.location;Point[] content = new Point[4];element.content.CopyTo(content, 0);for (int i = 0; i < content.Length; i++){ content[i].X = location.X + content[i].X; content[i].Y = location.Y + content[i].Y;}onPartialChanged(location,content,direction); } //判断游戏是否结束 if (onCompleted != null) {if (checkComplete()) { onCompleted();} } //全部变更 if (onFullChanged != null) {//判断是是否有权为1的行,如果有则消掉int[] rows = checkAllTetris();if (rows.Length>0){ updateAllTetris(rows);//消掉行 onFullChanged(tetris);} } return tmp;}/// /// 更新tetris/// /// private void updateTetris(TetrisElement element){ Point location = element.location; Point[] content = element.content; int minX = element.getMinX(element.style); int maxX = element.getMaxX(element.style); int minY = element.getMinY(element.style); int maxY = element.getMaxY(element.style); foreach (Point p in content) {if (location.Y + p.Y < 20 && location.Y + p.Y >= 0 && location.X + p.X >= 0 && location.X + p.X < 10){ this.tetris[location.X + p.X, location.Y + p.Y] = 1;} }}/// /// 检查全部列/// private int[] checkAllTetris(){ List lst = new List(); //20行 for (int y = 0; y < 20; y++) {int col = 0;//10列for (int x = 0; x < 10; x++){ if (tetris[x, y] == 0) {break; } else {col += 1; }}if (col == 10){ col = 0; lst.Add(y);} } return lst.ToArray();}/// /// 更新/// private void updateAllTetris(int[] rows) { foreach (int row in rows) {//当前行清掉for (int x = 0; x < 10; x++) { tetris[x, row] = 0;}//row行之上的往下移动一行for (int y = row-1; y >=0; y--) { for (int x = 0; x < 10; x++) {if (tetris[x, y] == 1) { tetris[x, y + 1] = 1; tetris[x, y] = 0;} }} }}/// /// 判断游戏是否结束/// /// private bool checkComplete() { bool isComplete = false; for (int i = 0; i < 10; i++) {if (tetris[i, 0] == 1) { isComplete = true; break;} } return isComplete;}/// /// 更新得分/// /// public void updateScore(int s) { this.scorce = this.scorce + s;}/// /// 重置信息/// public void Reset() { this.tetris = new int[10, 20]; this.scorce = 0;} }

5. 随机生成方块元素和起始位置

/// /// 静态函数,生成Tetris元素对象/// /// public static TetrisElement generate(){ Random r = new Random(0); //随机生成形状 int tstyle = getRandom(); tstyle = tstyle % 7; TetrisStyle style = TetrisStyle.I; style = (TetrisStyle)Enum.Parse(typeof(TetrisStyle), tstyle.ToString()); //随机生成起始坐标 int x = getRandom(); x = x % 10; int y = 0; //根据形状生成位置信息 TetrisElement element = new TetrisElement(style); //内容由四个点组成,顺序:先上后下,先左后右 Point[] content = element.getContent(style); //获取最小坐标和最大坐标,防止越界 int minX = element.getMinX(style); int minY = element.getMinY(style); int maxX = element.getMaxX(style); int maxY = element.getMaxY(style); //修正起始坐标 x = (x = maxX) ? maxX : x; y = minY; Point location = new Point(x, y); element.location = location; element.content = content; return element;}

备注

源码下载链接

以上就是C# 实现俄罗斯方块(附源码)的详细内容,更多关于C# 实现俄罗斯方块的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:C#实现俄罗斯方块基本功能C#实现简单俄罗斯方块基于C#实现俄罗斯方块游戏