1. 把每个砖块当成一个对象。每个砖块都有共同的行为,就是可以左移、 右移、下移和变形。既然这是他们共同的行为(方法),那么可以定义一个虚基类Brick,然后在该基类中声明这些行为。当然,砖块在做这些行为前需要知道能不能进行这些行为,比如说到了左边界就不能左移;到了下边界就不能下移;周围空间不够大,就不能变形等等。因此该基类还需要声明一些虚函数:CanTransform() CanLeftMove() CanRightMove() CanDropMove()等。
2. 继承定义的基类,每种砖块根据自身的形状具体实现相应函数。据说在标准的俄罗斯方块中,一共有七种形状。本练习项目中定义的方块和变形方式(绕着中心点顺时针旋转,途中颜色较深的点就是中心点)如下:
根据上图就可以知道,表示砖块最好的方法就是用二维数组了。对于砖块而言,这个二维数组就是它的变形范围,数组中的数字为0,代表砖块在该区域中无显示,为1代表有显示。在实现CanTransform() CanLeftMove() CanRightMove() CanDropMove()这四个函数时,要尤其小心,这边是最容易出错的地方。
3. 完成砖块下面就要进行画布的处理了。可以想象一下,把画布分成多个方格,也就相当于二维数组了,然后把砖块所对应的二维数组按指定的位置放到代表画布的二维数组中。在显示的时候就可以根据值为1的方格来获取位置并进行绘图了。所以,该项目中定义了一个名为Canvas的类,核心功能是用于获取这个二维数组的值,其中包含根据砖块设置数组的值、行满(一行里所有的值都为1)之后消除、超出高度后返回失败等。
4.真正的绘图操作。根据二维数组的值绘制pictureBox1,并响应方向键操作。
注意点:
1. pictureBox1的Refresh()函数会导致界面闪烁,所以需要采用双缓冲来进行绘图。相关代码如下:
private void Draw() { //初始化画布 Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height); Graphics gb = Graphics.FromImage(canvas); //... //绘图操作 //... pictureBox1.BackgroundImage = canvas; pictureBox1.Refresh(); }
2. Form中添加了按钮后,方向键的KeyDown消息就不响应了。原因:方向键是作为系统键来处理的,默认方向键的作用是移动焦点,所以按方向键的效果是焦点不断地在按钮之间转换。也就是说,按方向键产生的消息被系统处理掉了,那么我们自己定义的消息响应函数就不会执行了。解决方案:覆盖默认的系统键处理方式,如果是方向键就直接返回。代码如下:
protected override bool ProcessDialogKey(Keys keyData) { if (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Left || keyData == Keys.Right) { return false; } return base.ProcessDialogKey(keyData); }
好了,就写这么多,写得不好,大家见谅。项目下载地址:http://yun.baidu.com/share/link?shareid=3911360935&uk=3508115909