相信90后或者80后都玩过这款小游戏,一直想干一票,琢磨一下,但又不太懂,于是网上搜集修改就有了以下效果!bug较多,多多包涵!
1.效果展示
2.实现方法
参考https://blog.csdn.net/qian_f/article/details/19758671 感谢博主分享,我在这里也没修改啥,有时间修复几个bug
2.1对象分析
把每个砖块当成一个对象。每个砖块都有共同的行为,就是可以左移、 右移、下移和变形。既然这是他们共同的行为(方法),那么可以定义一个虚基类Brick,然后在该基类中声明这些行为。当然,砖块在做这些行为前需要知道能不能进行这些行为,比如说到了左边界就不能左移;到了下边界就不能下移;周围空间不够大,就不能变形等等。因此该基类还需要声明一些虚函数:CanTransform() CanLeftMove() CanRightMove() CanDropMove()等。
2.2继承实现
继承定义的基类,每种砖块根据自身的形状具体实现相应函数。据说在标准的俄罗斯方块中,一共有七种形状。本练习项目中定义的方块和变形方式(绕着中心点顺时针旋转,途中颜色较深的点就是中心点)如下:
根据上图就可以知道,表示砖块最好的方法就是用二维数组了。对于砖块而言,这个二维数组就是它的变形范围,数组中的数字为0,代表砖块在该区域中无显示,为1代表有显示。在实现CanTransform() CanLeftMove() CanRightMove() CanDropMove()这四个函数时,要尤其小心,这边是最容易出错的地方。
2.3画布处理
完成砖块下面就要进行画布的处理了。可以想象一下,把画布分成多个方格,也就相当于二维数组了,然后把砖块所对应的二维数组按指定的位置放到代表画布的二维数组中。在显示的时候就可以根据值为1的方格来获取位置并进行绘图了。所以,该项目中定义了一个名为Canvas的类,核心功能是用于获取这个二维数组的值,其中包含根据砖块设置数组的值、行满(一行里所有的值都为1)之后消除、超出高度后返回失败等。
2.4绘图
真正的绘图操作。根据二维数组的值绘制显示,并响应方向键操作。
3.代码实现
Block基类
1 public abstract class Block 2 { 3 protected int _curChangeTimes; //变化次数 4 public int _needRows; //行数 5 public int _needColumns; //列数 6 public int[,] _range; //变化范围 7 public Point _center; //中心点 相对于必要区域 8 public Point _Pos; //中心点位置,相对于画布 9 10 11 /// <summary> 12 /// 能否变形 ,能变形的条件为在方块的变形范围内不能有其它的方块 13 /// </summary> 14 /// <param name="arr"></param> 15 /// <param name="rows"></param> 16 /// <param name="cloumns"></param> 17 /// <returns></returns> 18 public abstract bool CanChange(int[,] arr ,int rows,int cloumns); 19 20 /// <summary> 21 /// 变形 22 /// </summary> 23 public abstract void Change(); 24 25 /// <summary> 26 /// 能否左移动 27 /// </summary> 28 /// <param name="arr"></param> 29 /// <param name="rows"></param> 30 /// <param name="columns"></param> 31 /// <returns></returns> 32 public abstract bool CanLeftMove(int[,] arr,int rows,int columns); 33 34 /// <summary> 35 /// 左移 36 /// </summary> 37 public void LeftMove() 38 { 39 _Pos.Y -= 1; 40 } 41 42 /// <summary> 43 /// 能否右移 44 /// </summary> 45 /// <param name="arr"></param> 46 /// <param name="rows"></param> 47 /// <param name="columns"></param> 48 /// <returns></returns> 49 public abstract bool CanRightMove(int[,] arr, int rows, int columns); 50 51 52 /// <summary> 53 /// 右侧移动 54 /// </summary> 55 public void RightMove() 56 { 57 _Pos.Y += 1; 58 } 59 60 /// <summary> 61 /// 能否下移 62 /// </summary> 63 /// <param name="arr"></param> 64 /// <param name="rows"></param> 65 /// <param name="columns"></param> 66 /// <returns></returns> 67 public abstract bool CanDownMove(int[,] arr, int rows, int columns); 68 69 70 /// <summary> 71 /// 下侧移动 72 /// </summary> 73 public void DownMove() 74 { 75 _Pos.X += 1; 76 } 77 78 79 /// <summary> 80 /// 随机生成一个可以通过变形得到的形状 81 /// </summary> 82 public void RandomShape() 83 { 84 Random random = new Random(); 85 this._curChangeTimes = random.Next(4); 86 this.Change(); 87 } 88 89 /// <summary> 90 /// 设置中心点相对于画布的位置 91 /// </summary> 92 /// <param name="x">横向位置</param> 93 /// <param name="y">纵向位置</param> 94 public void SetCenterPos(int x, int y) 95 { 96 this._Pos = new Point(x, y); 97 } 98 99 /// <summary> 100 /// 获取方块出现时中心点的Y轴坐标 101 /// </summary> 102 /// <returns></returns> 103 public abstract int Appear(); 104 }