C#实现俄罗斯方块
2014-02-23 19:24
411 查看
折腾好久,我的C#练手项目“俄罗斯方块”终于告一段落了。不多说,先看下效果图再来稍微讲解下。
截图如下:
实现方法:
1. 把每个砖块当成一个对象。每个砖块都有共同的行为,就是可以左移、 右移、下移和变形。既然这是他们共同的行为(方法),那么可以定义一个虚基类Brick,然后在该基类中声明这些行为。当然,砖块在做这些行为前需要知道能不能进行这些行为,比如说到了左边界就不能左移;到了下边界就不能下移;周围空间不够大,就不能变形等等。因此该基类还需要声明一些虚函数:CanTransform() CanLeftMove() CanRightMove() CanDropMove()等。
2. 继承定义的基类,每种砖块根据自身的形状具体实现相应函数。据说在标准的俄罗斯方块中,一共有七种形状。本练习项目中定义的方块和变形方式(绕着中心点顺时针旋转,途中颜色较深的点就是中心点)如下:
根据上图就可以知道,表示砖块最好的方法就是用二维数组了。对于砖块而言,这个二维数组就是它的变形范围,数组中的数字为0,代表砖块在该区域中无显示,为1代表有显示。在实现CanTransform() CanLeftMove() CanRightMove() CanDropMove()这四个函数时,要尤其小心,这边是最容易出错的地方。
3. 完成砖块下面就要进行画布的处理了。可以想象一下,把画布分成多个方格,也就相当于二维数组了,然后把砖块所对应的二维数组按指定的位置放到代表画布的二维数组中。在显示的时候就可以根据值为1的方格来获取位置并进行绘图了。所以,该项目中定义了一个名为Canvas的类,核心功能是用于获取这个二维数组的值,其中包含根据砖块设置数组的值、行满(一行里所有的值都为1)之后消除、超出高度后返回失败等。
4.真正的绘图操作。根据二维数组的值绘制pictureBox1,并响应方向键操作。
注意点:
1. pictureBox1的Refresh()函数会导致界面闪烁,所以需要采用双缓冲来进行绘图。相关代码如下:
2. Form中添加了按钮后,方向键的KeyDown消息就不响应了。原因:方向键是作为系统键来处理的,默认方向键的作用是移动焦点,所以按方向键的效果是焦点不断地在按钮之间转换。也就是说,按方向键产生的消息被系统处理掉了,那么我们自己定义的消息响应函数就不会执行了。解决方案:覆盖默认的系统键处理方式,如果是方向键就直接返回。代码如下:
好了,就写这么多,写得不好,大家见谅。项目下载地址:http://yun.baidu.com/share/link?shareid=3911360935&uk=3508115909
截图如下:
实现方法:
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
相关文章推荐
- C#委托与事件的区别
- C#中的继承(一)
- C# 将字节流转换为图片的实例方法
- Selenium for C#的入门Demo
- c#中为什么有些类要声明为静态类?
- 【PYC#1 欢乐赛】 题解
- C#常用数据类型间的转换
- C#中有“静态类”的概念
- 处理VC开发的webservice在C#.NET中中文乱码问题
- C# webBrowser 开新窗口保持Session
- 初学者容易混淆和不理解的一些C#关键字
- c#全选文件
- 【已解决】C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件
- c# 1-2+3-4.....求和
- C# (WebKit初探)WebKit.net最简单使用方法
- C#的一个过程!
- 在C#(C sharp)中数组和集合的区别及他们的初始化器
- 移动开发之Xamarin+C#环境搭建
- [转载]C#中各种计时器
- C#中StreamWriter与BinaryWriter的区别兼谈编码。