大小: 5121
备注:
|
大小: 7747
备注:
|
删除的内容标记成这样。 | 加入的内容标记成这样。 |
行号 42: | 行号 42: |
== 把它们结合起来 == 到此时,这两个类看来还很简单。没有比一个简单的列表和一个自己的游戏对象类好多少。但是把Sprite和Group用在一起就能有很大的好处了。一个Sprite可以属于你想要的任意多的group。记住一旦一个Sprite不属于任何一个Group,它通常会被自动清除掉(除非你在Group外存在引用引用了那个Sprite对象) The first big thing is a fast simple way to categorize sprites. For example, say we had a pacman-like game. We could make separate groups for the different types of objects in the game. Ghosts, Pac, and Pellets. When pac eats a power pellet, we can change the state for all ghost objects by effecting everything in the Ghost group. This is quicker and simpler than looping through a list of all the game objects and checking which ones are ghosts. Adding and removing groups and sprites from each other is a very fast operation, quicker than using lists to store everything. Therefore you can very efficiently change group memberships. Groups can be used to work like simple attributes for each game object. Instead of tracking some attribute like "close_to_player" for a bunch of enemy objects, you could add them to a separate group. Then when you need to access all the enemies that are near the player, you already have a list of them, instead of going through a list of all the enemies, checking for the "close_to_player" flag. Later on your game could add multiple players, and instead of adding more "close_to_player2", "close_to_player3" attributes, you can easily add them to different groups for each player. Another important benefit of using the Sprites and Groups, the groups cleanly handle the deleting (or killing) of game objects. In a game where many objects are referencing other objects, sometimes deleting an object can be the hardest part, since it can't go away until it is not referenced by anyone. Say we have an object that is "chasing" another object. The chaser can keep a simple Group that references the object (or objects) it is chasing. If the object being chased happens to be destroyed, we don't need to worry about notifying the chaser to stop chasing. The chaser can see for itself that its group is now empty, and perhaps find a new target. Again, the thing to remember is that adding and removing sprites from groups is a very cheap/fast operation. You may be best off by adding many groups to contain and organize your game objects. Some could even be empty for large portions of the game, there isn't any penalties for managing your game like this. |
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对象)
The first big thing is a fast simple way to categorize sprites. For example, say we had a pacman-like game. We could make separate groups for the different types of objects in the game. Ghosts, Pac, and Pellets. When pac eats a power pellet, we can change the state for all ghost objects by effecting everything in the Ghost group. This is quicker and simpler than looping through a list of all the game objects and checking which ones are ghosts.
Adding and removing groups and sprites from each other is a very fast operation, quicker than using lists to store everything. Therefore you can very efficiently change group memberships. Groups can be used to work like simple attributes for each game object. Instead of tracking some attribute like "close_to_player" for a bunch of enemy objects, you could add them to a separate group. Then when you need to access all the enemies that are near the player, you already have a list of them, instead of going through a list of all the enemies, checking for the "close_to_player" flag. Later on your game could add multiple players, and instead of adding more "close_to_player2", "close_to_player3" attributes, you can easily add them to different groups for each player.
Another important benefit of using the Sprites and Groups, the groups cleanly handle the deleting (or killing) of game objects. In a game where many objects are referencing other objects, sometimes deleting an object can be the hardest part, since it can't go away until it is not referenced by anyone. Say we have an object that is "chasing" another object. The chaser can keep a simple Group that references the object (or objects) it is chasing. If the object being chased happens to be destroyed, we don't need to worry about notifying the chaser to stop chasing. The chaser can see for itself that its group is now empty, and perhaps find a new target.
Again, the thing to remember is that adding and removing sprites from groups is a very cheap/fast operation. You may be best off by adding many groups to contain and organize your game objects. Some could even be empty for large portions of the game, there isn't any penalties for managing your game like this.
= The end =