[pygame]有趣的游戏循环
不知道大家是怎么写pygame的绘制、时间循环的?像下面这样?
while True: for event in pygame.event.get(): if event.type == QUIT: return #game loop...
很多教程,都很简单地使用了这样的循环……可惜的是这样跳出循环很容易导致很多问题,一是程序结构不好看(《DOM scripting with Javascript》的作者说的);二是,如果你的绘制代码是放在其他线程的话或者绘制代码时间滞后了,那个线程、那段代码可能会先抛出一个不明不白的“错误”才让你退出(至少对用户来说是这样)。
我以前也这样做,于是我的朋友问我,为什么你说你的程序做好了,但退出时却有一个令人费解的对话框出现啊?
我以前不太注重这些细节,因为对于我们来说,这些东西对使用时没有影响的。但对于用户来说,他们不知道我在程序里确切干了些什么,总会有一点害怕,害怕我把他的电脑搞坏了,或者怀疑自己的硬件有问题到维修店白跑一遍……呵呵,说得有点夸张了。
于是,我去pygame.org看看有没有人写出更好的循环结构呢?找到了一个……
while True: clock.tick(15) #game loop... for event in pygame.event.get(): if event.type == pygame.locals.QUIT: raise SystemExit
这次把return改为raise SystemExit了,这样整个系统都会退出,这样基本上不会出现Windows那个什么提示错误的对话框了……然而,终端运行还是有问题,抛出了一个虚拟机退出而线程未完全退出的异常,不过对于Windows用户来说关系不大——他们大概不会在cmd下运行这个程序吧?但对于追求一个完美的结局,这样的结构显然还不够好……
while pygame.display.get_init(): clock.tick(60) pygame.display.update() for event in pygame.event.get(): if event.type == QUIT: t.running = False #退出线程 pygame.quit() #退出pygame模块
这样就好了,循环根据pygame的display模块是否退出来判断是否继续执行,退出之前通知所有线程停止执行。(但对于线程执行时间滞后问题还是没有很好地解决)
其实都是具体问题具体分析,暂时还没有发现一个更好的方案了……
不知道大家有没有更好的循环写法呢?
[pygame]对象碰撞检测(二)
上一篇文章写了一个不完整的介绍,现在继续写它,当然,也是不完整的。
其实都是pygame 1.8.1更新的函数,由于没有中文资料,写写吧……虽然现在英文文档已经更新了。
以下所说的Sprite指的是继承了pygame.sprite.Sprite类的对象。
PyGame 1.8.1提供的新函数/类:
就写这三个吧。
用于把Sprite的面积(rect属性,继承自pygame.Rect类)扩大ratio倍再进行比较,返回的是一个函数。它不会对Sprite的rect进行真实的扩大/缩小。
返回的函数可以作为
中collided参数使用的(见上一篇文章)。但注意的是,这个不是一个函数,而是一个类,collided参数用的是这个类的实例,和上篇文章不同。
简化了自己编写自定义碰撞检测的麻烦,不过该函数仅仅对两个Sprite的rect扩大ratio倍再比较面积是否相交。
与之相似的是
不过,这个函数要求Sprite必须有radius属性(半径),根据半径扩大ratio倍。
这也是个类,定义与用法与pygame.sprite.collide_rect_ratio(ratio): return collided_callable相似。
left和right分别代表一个Sprite,事实上与Sprite所处的位置并没有要求(并不是规定left和right)。但这两个Sprite需要有额外的radius属性(表明半径)。
返回一个boolean(是否相交的布尔值)。这个函数也可以作为
的collided参数使用。但和上两个类不同,这是一个函数,需要把这个函数的引用作为参数(例如:collided = pygame.sprite.collide_circle不需要括号)。
其实这些类或许在实际使用pygame模块没有什么用处,不过提供给我们一个对游戏中对象碰撞检测的参考~~~
[PyGame]碰撞检测
PyGame 1.7在pygame.sprite里为碰撞检测提供了三个函数:
sprite - pygame.sprite.Sprite对象
group - pygame.sprite.Group对象(或其子类对象)
dokill - 是否杀死group中与sprite碰撞的sprite对象
返回包含所有group中与sprite相撞的sprite的列表(list)
groupa - pygame.sprite.Group对象(或其子类对象)
groupb - pygame.sprite.Group对象(或其子类对象)
dokilla - 是否杀死groupa中与groupb中碰撞的sprite对象
dokillb - 是否杀死groupb中与groupa中碰撞的sprite对象
返回包含所有groupa中与groupb相撞的sprite的字典(dict)
和spritecollide(sprite, group, dokill)相似,但只是返回group中最第一个与sprite相碰撞的sprite。
PyGame模块学习:Sprite
发现PyGame文档中的中文资料甚少,学习PyGame真的有点困难,但是Python又是如此容易学习的语言,不肯放弃。
我想许多人会对pygame.sprite.Sprite类不理解,至少我是这样,我看过一些程序后也还是觉得有点抽象──它到底如何绘制的呢?(绘制pygame.sprite.Sprite类里的哪个东西?)