TableOfContents

Sprite模块介绍

Pygame 1.3版本开始有了一个新的模块pygame.sprite。这个模块由python写成,包括一些高级的管理游戏对象的类。充分利用这个模块,可以简化游戏对象的管理和绘制。sprite类是高度优化的,你的游戏如果用sprite模块很可能比不用还要快。

sprite模块也是非常通用的。你可以用它进行几乎任何类型的游戏开发。灵活性总是要有代价的,要正确使用它需要对它有一些了解。sprite模块的参考文档可以让你把它用起来,但是对于怎么在你的游戏里面使用pygame.sprite还需要更多的解释。

一些pygame的例子(像"chimp"和"aliens")已经开始使用sprite模块了。你可能要先看一下那些例子,来了解sprite模块是做什么的。chimp模块甚至有他自己每一行代码的解释,这样可以帮助你更好地了解用Python和pygame来编程。

注意,本文假设你已经了解python编程,并且对于创建一个简单游戏的各种部分已经有一点了解。在本文里面,引用这个词很少使用。这代表一个Python的变量。变量在python里面就是引用,因此你可以有好几个变量都指向同一个对象。

1. 历史知识

sprite这个词,是从很老的计算机和游戏机上遗留下来的。这些老的机器不能够像游戏里需要的那样很快的画图形和删除图形。对于像游戏里那些变化很快的对象,这些机器需要一个特别的硬件去处理。这些对象叫做sprites,并且对它们有一些特殊的限制,但是可以把它们很快的画出来以及很快的更新它们。它们通常被存在视频里面一个特殊的层的缓存上。现在计算机已经够快,从而不需要特别的硬件去处理sprite了。而sprite这个词仍然被用来表示2D游戏里面任何会动的东西。

2. 类

sprite模块有两个主要的类。一个是Sprite,用作所有游戏对象的基类。这个类本身实际上什么事情也不作,它只是包含了一些可以帮助对象管理的函数。另一个类是Group,它是各种不同的Sprite对象的容器。实际上有几种不同类型的group类,比如说有些Group类可以把所有它包含的Sprite画出来。

这就是它所有的东西了。我们首先描述这些类每一个都是做什么的,然后再讨论如何正确的使用它们。

3. Sprite类

刚才提过,Sprite类是用作所有游戏对象的基类的。它本身几乎没有什么用处,因为它只包含几个函数来和各种Group类一起工作。Sprite保留了它自己属于哪个Group的信息。类的构造函数__init__可以用一个Group(或者多个Group的列表)作为参数,指明这个Sprite属于哪些Group。你还可以通过Sprite的add和remove方法来修改它属于哪些Group。还有一个groups方法,可以返回它现在属于的Group的列表。

当使用你的Sprite类的时候,如果它属于某一个或者多个Group,则它被称为是"有效的"或者说是"活的"。当你把这个Sprite从所有的组里面删除时,pygame会清除这个对象(除非你其他地方还有引用这个对象)。kill方法把这个sprite从所有组里面删掉。这会完全删除这个Sprite对象(译注:这不完全正确)。如果你一些小游戏组合在一起,你有时候很难完全清除一个游戏对象。Sprite对象还有一个alive方法,如果Sprite对象还属于其他某个Group则返回True。

4. Group类

Group类只是一个简单的容器。和sprite类似,它也有add和remove方法,用来改变它所包含的Sprites。你可以给它的构造函数传一个Sprite或者一组Sprite作为一开始它所包含的sprite对象。

Group还有其他一些函数,比如empty用来删除group里面的所有对象,copy用来创建一个新的group,包含的Sprite成员和原来的一样。还有一个has方法可以快速判断一个sprite或者一组sprite是否在一个group里面。

其他用的很多的函数还有sprites函数。它返回一个对象,遍历它可以访问Group所包含的所有Sprite对象。现在它返回的这个对象是Sprite的列表,以后可能会变成迭代子以提高性能。

作为一种便捷途径,Group还有一个update方法,它会调用它所包含的所有Sprite的update方法,并且Group的update的参数会传给所有的Sprite的update方法。通常游戏里需要一个函数来更新游戏对象的状态。虽然通过Group.sprites方法调用每一个sprite的方法也是很容易的,但是它经常被用到,所以就被加入进来作为一种便捷方式。还要注意,Sprite基类有一个"dummy"(愚蠢的什么都不会作的)的update方法,可以带任何参数,却什么也不作。

最后,Group类有几个其他方法允许你使用python内置的len函数来获得它包含的Sprite的个数,还有一个bool运算符允许你像"if mygroup:"这样来检查group是否包含sprite。

5. 把它们结合起来

到此时,这两个类看来还很简单。没有比一个简单的列表和一个自己的游戏对象类好多少。但是把Sprite和Group用在一起就能有很大的好处了。一个Sprite可以属于你想要的任意多的group。记住一旦一个Sprite不属于任何一个Group,它通常会被自动清除掉(除非你在Group外存在引用引用了那个Sprite对象)

第一个大好处就是可以很简单快速的组织sprites。比如说,我们做一个类似pacman(吃豆)的游戏。我们可以把游戏里面不同类型的对象分开成不同的group:Ghost、Pac、Pellets。当pac吃到一个强力的pellet,我们可以通过改变Ghost Group里面的所有东西来改变所有ghost对象的状态。这样比循环迭代所有游戏对象,并检查每一个对象是不是Ghost要简单和快速得多。

从Group里添加和删除Sprite以及从Sprite里面添加和删除Group都是非常快的操作,比使用list来存储它们还要快。因此,你可以非常高效的改变Group的成员。Group可以作为每一个游戏对象的一个简单属性一样工作。你可以把Sprite添加到各种不同的Group,而不是为对象添加属性(比如为一堆敌人对象添加"close_to_player"属性)。当你要访问靠近玩家的所有敌人对象,你已经有它们的一个列表了,而不是访问所有敌人的列表并检查"close_to_player"标志。如果以后你要添加多个玩家,你不用为敌人对象添加"close_to_player2"、"close_to_player3"属性,而只要简单的把它们加到每个玩家对应的Group里面去。

使用Sprite和Group另一个重要的好处是,Group可以非常清晰的控制游戏对象的清除(或者称作杀死)。在一个游戏里面,很多对象都引用另外很多对象,有时删除对象会成为最困难的事情,因为除非它不再被引用否则它就不会被清除。假设我们有一个对象,它"追逐"另一个对象。追逐者可以保留一个Group,包含它追逐的对象。追逐者可以看到自己的Group是空了,可能要找一个新的目标。

再重申一次,要记住从Group里面删除和添加Sprite是非常快速廉价的操作。你可以添加很多Group来包含和管理你的游戏对象。有一些Group甚至可以是空的,这样没有任何坏处。

The end

ch3n2k.com | Copyright (c) 2004-2020 czk.