用Python和Pygame写游戏-从入门到精通(实战二:恶搞俄罗斯方块1)

479 查看

游戏是为了什么而存在的?Bingo,是为了娱乐~ 在这个最高主题之前,技术啥的什么都无所谓!

前一段时间,有位姓刘的网友用Pygame写了个俄罗斯方块,在用py2exe打包的时候遇到一些问题,和我交流了一下。有兴趣的可以在这里下载,除了代码,打包后的exe文件也一并提供了。

受他启发,这次我们就以俄罗斯方块为主题做一个游戏吧,但是,咱不能走寻常路啊,得把它整的非常有趣才行。记得曾经在网上看到一个搞笑俄罗斯方块(视频地址),当时看了笑到肚子疼啊,时隔很久现在翻出来,一样笑到脱力:

我们就来做一个这样的俄罗斯方块吧:)做好了以后,给朋友玩玩,好好看看他(她,它?)的囧表情!

构架原理

构架这个词太大了,其实就是草稿了~ 看过这个视频,我们可以看到这个蛋疼的游戏有几种模式,把几个可能用到我们游戏中的模式分别整理一下:

  • 落下立刻消失
  • 一屏幕长的长条
  • 掉各种房间的方块,挂了以后算房钱
  • 长条的宽度稍稍宽于一般尺寸
  • 落下奇怪的东西(豆荚,气泡等)
  • 长条会从底部消失
  • 方块非常非常小
  • 同时快速落下三个方块
  • 落下超级玛丽,碰到蘑菇长大挂掉
  • 当然我们至少得有一个正常的模式

非常的多,不过这个界面还是都一样的,不同的是我们掉下的东西和消除判断。我们先把UI考虑一下,就用普通的俄罗斯方块的界面就可以了,像这样:

虽说相当不酷,不过各个部分一目了然,应该也可以了。分别是游戏显示区,右边则是下一个方块的显示,得分显示区域,和一些功能按钮。

接下来我们考虑这个程序的运行机理,我们先从最基本的情况开始。在经典俄罗斯方块运行的时候,不停的有随机的方块落下,用户控制它们的转向和位置落下,落下以后,如果稳固的方块堆有哪一行是完全填充的,就消除得分。

俄罗斯方块的思想其实非常的简单,人们热衷于它,不得不说简单又有有足够变化的规则是主因,还有就是用户受众很大的关系……

右半部分的都很简单,分别是下一个方块,分数和一些功能按钮,左半部分是和谐,这里得不停的刷新,因为方块不管有没有操作都会缓慢落下直至完全落地。而一旦落地,就需要看是否消除并刷新分数,同时落下接着的方块,并显示下一个方块。

原理的进一步思考

俄罗斯方块诞生于1985年,那时候还没有什么成熟的“面向对象”的编程方法,所以俄罗斯方块从一开始,界面就是以古朴的数组的方式运行的。

如果你有用其他语言编写俄罗斯方块的经验的话,就会知道大多数的实现方法都是维护一个二维数组(长度对应区域中的格子数,比如20×10。当然也可以是一维的,因为知道宽度,所以转换很容易),当数组某一位是1的时候,说明对应的位置有方块,这个数组不停的更新,程序就把这个数组实时的画到屏幕上,如此而已。

我们再考虑的仔细一点,因为是使用pygame编写,有没有什么更好的方法呢?如果我们把每一个方块(这里指四个小方块组成的整体)当做一个Sprite,那么就可以很方便的绘制,但是Sprite总是方形的,做碰撞判断就无效了,所以这样不行。那如果把每一个小方块作为一个Sprie,再把四个小方块组成的放开做一个Group呢?听起来不错,但是再想想也非常麻烦,我们就得判断碰撞的方向,要多做很多事情……考虑良久,感觉还是使用数组最靠谱啊,真可惜!所以我们也还是用数组来做这事情吧。

实现初期的一些优化思考

尽管我们仍然使用数组这种“古老”的方式,我们还是应该要利用一下pygame的绘图优势,否则就太失败了。举个例子,一般的俄罗斯方块,在重绘的时候把数组从头到尾扫描一遍,碰到一个1就画一个方块,俄罗斯方块的刷新率就算很低,一秒钟也要画了好多次吧(否则后期速度快的时候画面就“顿”了)。算它是15次,这样一来,每秒钟要扫描15次,需要画几百甚至上千次方块,调用这么多次绘图函数,还是相当浪费资源的。

我们可以这么考虑,除了数组之外,我们还维护一个已经落下的方块的图形的Surface,这样每次只需要把这个Surface贴到屏幕上就可以了,非常的轻量级。而这个Surface的更新也只需要在新的方块着地以后进行,完全可以在判断消除的代码里一起做,平均几秒钟才会执行一次,大大减少了计算机的工作了。当然,这个简单的程序里,我们这么做也许并不能看到性能的提升,不过一直有这么的思想,当我们把工程越做越大的时候,和别人的差距也许就会体现出来了。

同时,出于人性化的思考,我们是不是可以提供用户点击其他窗口的时候就把游戏暂停了?实现起来并不困难,但是好感度的提升可是相当的大。

实现中的一些细节

按左向左,按右向右,这一点事毫无疑问的,不过当我们按着向左向右不放的时候,就会持续移动,这一点也是要注意的,上面那位朋友实现的俄罗斯方块就没有考虑这一点,当然可能还是中途的版本的关系,我们这里要考虑到。

因为我们要实现几种不同模式的俄罗斯方块,那么比较一般的考虑方法就是先实现一个通用的、标准的而定制能力又很强的游戏类。当我们以后去做其他模式的时候,可以很方便的从这个类扩展出来,所以一开始设计的时候,就要尽可能多的考虑各种变种。

另外,考虑这次就完全使用键盘来控制吧,鼠标就不要了,上面的概念图,旁边几个按钮请无视……

下一次开始,我们就从基本的框架开始,慢慢地搭一个不同寻常的俄罗斯方块出来。