最近在学习Python,所以上网找了一个小程序练练手。

关于这款名为【Bunny】的小游戏,详细请看下面的链接:

http://www.oschina.net/translate/beginning-game-programming-for-teens-with-python

这篇文章里面对游戏的所有代码都做了非常详细的说明,可以说就算是零基础的新手,也能在完整地抄写完代码后,就会对Python有个比较大概的了解。

更妙的是,这篇文章还附带有游戏所需的图片及声音文件,不需要再花费额外的时间去寻找素材。

如果你有Python的一点点基础,那么就只需要花3个小时的时间(甚至更短),就能做出一个小游戏出来,这让人非常有成就感。

不过这毕竟只是一个练手的小游戏,更多地是向新手介绍Python和Pygame的入门,因此在结构上偏向于面向过程,算是一个小小的缺憾吧。

因此我在源代码的基础上,对代码做了面向对象化的重构。

重构后的代码可见文章最后的链接。

首先将整个游戏做了一次封装,将主要的逻辑部分放入一个叫Game的类中。

因此在运行游戏时,只需执行:

from Game import Game

game = Game()
game.run()

就够了。

接下来就是对游戏各元素进行封装,大概可参考下图:

上图是我用EXCEL大概画的一个UML类图,不是很精通,如果错误,请见谅。

从上图可知,整个程序包括:

  1个Game主类

  2个工具类

  3个继承自pygame.sprite.Sprite的精灵类

组成。

Game里主要是负责逻辑判断,以及画面的调用绘制。

3个精灵类则非常简单,只有包含精灵图片以及位置的初期化设置,以及详细的绘制方法。

2个工具类中,AudioManager主要负责游戏初期时的音效导入,TextUtil只负责画面上时钟的绘制。这样在Game主类中就不要长篇累牍地写各控件的方法,只要简单调用一下就行。

其实工具类中本还应该有一个图片的初期化导入模块,由于时间的关系,没有单独抽调出来,而是直接写在Game方法里了。

关于精灵类的使用,因为图片导入时直接生成一个Surface对象,所以最初我想直接将这3个游戏对象继承自pygame.Surface类,以便可以方便调用。

但是在实际中我发现Surface对象不能单独作为一个子对象使用,否则就会在传递的过程中会报错,抛出:

Pygame: <Surface: (Dead Display)>

的异常。

这让我百思不得其解。最后在StackOverflow上看有人说只需要继承pygame.sprite.Sprite就可以了。

pygame.sprite.Sprite是pygame的基础类,包含所需的各种基本方法和属性。

而且Sprite中包含两个属性:image和rect,而且Sprite.image直接就可以返回一个Surface对象,足以满足要求。

pygame有一个pygame.sprite.OrderedUpdates 类,它相当于Sprite的Group,可以非常方便的添加和删除Sprite对象。

并且调用OrderedUpdates中的update()方法,可以直接调用所包含的对象的update(),省去对每个sprite对象进行绘制。

经实践证明,确实好用。

但是其中还有另外一个让我困惑的问题。

OrderedUpdates.draw()方法可以返回一组有变化的sprite对象。

如下代码,从官方网站提供的例子所示:

group = pygame.sprite.OrderedUpdates()
group.add(player) dirty = group.draw()
pygame.display.update(dirty)

画面上只有变动的sprite才会有所变化。在背景图不变的情况下,可以提高游戏的性能。

但是在实际操作中发现,这个方法不能清除脏画面。画面移动后,会留下残影,非常难看。

最后没有办法,只好用最土的方法,每次刷新画面的时候,需要将整个画面重新刷一次。

这个简单的小游戏中,由于对象非常少,所以看不出太大的延迟,但是只要将移动的精灵数量提高200以上就会发现游戏变得非常顿卡。

多方寻找无果,只好放弃,囧。

希望各位如果有好的方法,望请不啬笔力,能够指点一下。

重构后的代码链接:

https://git.oschina.net/RelaxCat/Bunny

Python 小游戏 Bunny的更多相关文章

  1. Python小游戏、小程序

    python 小游戏之摇骰子猜大小 python 实现一个双色球生成程序 python-循环与判断练习题

  2. Python小游戏之猜数字

    最近师兄师姐毕业,各种酒席,酒席上最常玩的一个游戏就是猜数字,游戏规则如下: 出题人在手机上输入一个0-100之间的数字,其它人轮流猜这个数字,如果你不幸猜中则要罚酒一杯.每次猜数字,出题人都要缩小范 ...

  3. Python小游戏之 - 飞机大战美女 !

    用Python写的"飞机大战美女"小游戏 源代码如下: # coding=utf-8 import os import random import pygame # 用一个常量来存 ...

  4. python 小游戏之摇骰子猜大小

    最近学习Python的随机数,逻辑判断,循环的用法,就想找一些练习题,比如小游戏猜大小,程序思路如下: 开发环境:python2.7 , 附上源代码如下: 摇骰子的函数,这个函数其实并不需要传任何参数 ...

  5. 玩Python小游戏猜数字,在游戏中掌握基础,你还能学不会?

    学python怎么离得开案例呢? 今天再继续给大家分享一个Python教程里的猜数字游戏     我最近也是在学python,从事编程工作几年了,但是python还是今年才开始玩的,不得不说,这真是一 ...

  6. python小游戏-水文

    脚本不会,全都白费.所以就去学习了简单的python,结果不慎学了python中的pygame,浪费了不少时间,没啥用如果不做游戏个人觉得最好别学,学爬虫她不香吗?不过也有一点收获,打飞机小游戏,源码 ...

  7. Python小游戏 -- 猜单词

    Python初学者小游戏:猜单词 游戏逻辑:就像我们曾经英语学习机上的小游戏一样,电脑会从事先预置的词库中抽取单词,然后给出单词的字母数量,给定猜解次数,然后让玩家进行猜测,并给出每次猜测的正确字母与 ...

  8. Python小游戏 -- 猜数字

    Python初学者小游戏:猜数字 游戏逻辑:电脑随机生成一个数字,然后玩家猜数字,电脑提示猜的数字大了还是小了,供玩家缩小数字范围,达到既定次数后,玩家失败.若在次数内猜对,玩家获胜. 涉及知识点:r ...

  9. Python小游戏之 - 飞机大战 !

    用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...

随机推荐

  1. Panabit安装配置笔记

    最近研究了linux下基于FREEBSD的开源流控软件Panabit,感觉功能还不错,单位公司如果经费不足的朋友需要做内网流控可以使用这款软件,最新免费版ISO镜像仅支持网桥模式和旁路模式,256个并 ...

  2. 装b指南

    提溜一个糖水黄桃罐头瓶,放在桌边,坐下以后,脖子略微后仰,翘着二郎腿,低头盯着屏幕看需求. 最好点一根烟,牌子无所谓,能冒烟就行.要得就是云山雾绕的感觉,从烟雾中眯着眼睛看出去,一副胸有成竹的样. 一 ...

  3. 数据结构与算法实验题6.1 s_sin’s bonus byFZuer

    玩家从n 个点n-1 条边的图,从节点1 丢下一个小球,小球将由于重力作用向下落,而从小球所在点延伸出的每一条边有一个值pi 为小球通过该条边的概率(注意从同一个节点向下延伸的所有边的pi 的和可以小 ...

  4. MySQL一次插入多行数据

    CREATE TABLE `viewhistory` ( `viewid` ) NOT NULL AUTO_INCREMENT, `uid` ) NOT NULL, `video` ) NOT NUL ...

  5. 用批处理启动MySQL命令行工具

    最近在看MySQL,安装好之后,每次在开始菜单去启动MySQL命令行工具的时候,都是直接用root用户连接我本地的数据库 输入密码开始工作,但是要连接服务器上的MySQL的话,就要去CMD下运行 : ...

  6. C# 条件编译备忘

    第一步:配置管理器中新建解决方案配置 第二步:定义条件编译符号: 第三步:在代码中使用自定义的条件编译 #if CustomDebug Console.WriteLine("dsads&qu ...

  7. ios UIButton 选中后背景图片变化发灰问题

    UIButton的类型如果选择了System类型,那么设置背景图后,点击的效果是图片发灰,而不是默认的那种图片变淡黑色效果,需要用customer类型就好了.

  8. (keymap设置及eclipse常用快捷键总结)

    设置pycharm为Eclipse快捷键后使用总结: Ctrl + O  根据name模糊查找当前文件中类.方法 Alt + (向左箭头或者向右箭头) ,回退or前进到到之前查看或者编辑处 Alt + ...

  9. java获取本月或某月的第一天和最后一天

    获取某月的第一天和最后一天的日期 Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Ca ...

  10. jquery stop( ) 的用法 (转)

    目的:为了 了解stop()的用法,举个例子,直观的方式看看. 实物:一个id="animater"的div包含了一段文字.(以下用animator表示实物) 动画最终的完整效果: ...