如何在Pygame中使用精灵组

13

现在我的程序已经到了需要为一些玩家可以与之碰撞而不死亡的精灵创建一个组的阶段(就像屏幕上可能有其他精灵一样)。

我已经仔细搜索了Google,但官方的pygame文档似乎没用或难以理解。我正在寻找任何了解此事的人提供一点点帮助。

首先,我需要找出如何创建一个组。这是在最初的游戏设置中完成吗?

然后在创建精灵时将其添加到组中。pygame网站在这个主题上有以下内容:

Sprite.add(*groups)

那么... 如何使用它呢?假设我有一个名为“gem”的精灵。我需要将gem添加到gems组中。是这样的吗:

gem = Sprite.add(gems)

我不太确定,但由于网站上没有任何示例供参考,我感到困惑。

此外,我希望能够编辑特定组的属性。这是通过像定义类一样定义组来完成的吗?还是在现有精灵的定义中进行定义,但使用“如果精灵在组中”的方式?


5
请更改问题的标题,使其描述您的问题。 - Sven Marnach
4个回答

18
回答你的第一个问题;要创建一个群组,你可以像这样做:
gems = pygame.sprite.Group()

然后添加一个精灵:

gems.add(gem)

就您想要编辑的组的属性而言,这取决于它们是什么。例如,您可以定义类似以下内容来指示组的方向:

gems.direction = 'up'

嗯。简短而甜美。逻辑也很清晰,现在我知道如何使用它了。谢谢! - user161592
1
没问题。您可能会发现这篇文章很有用 - http://www.devshed.com/c/a/Python/PyGame-for-Game-Development-Sprite-Groups-and-Collision-Detection/ - timc
1
这个答案对我帮助很大。谢谢! - 10 Rep

7

我知道这个问题已经有答案了,但最好的方法就像kelwinfc建议的那样。我会详细解释一下,以便更容易理解。

# First, create you group
gems = pygame.sprite.Group()

class Jewel (pygame.sprite.Sprite): # Inherit from the Sprite
    def __init__ (self, *args): # Call the constructor with whatever arguments...
        # This next part is key. You call the super constructor, and pass in the 
        # group you've created and it is automatically added to the group every 
        # time you create an instance of this class
        pygame.sprite.Sprite.__init__(self, gems) 

        # rest of class stuff after this.

>>> ruby = Jewel()  
>>> diamond = Jewel()  
>>> coal = Jewel()

# All three are now in the group gems. 
>>> gems.sprites()
[<Jewel sprite(in 1 groups)>, <Jewel sprite(in 1 groups)>, <Jewel sprite(in 1 groups)>]

你也可以使用 gems.add(some_sprite) 添加更多内容,同样可使用 gems.remove(some_sprite) 去除它们。

1
我浏览了所有内容才发帖,然后意识到你已经理解了这种方法。 :/ 哦,好吧,哈哈。 - jtsmith1287
1
在我看来,像这样使用全局变量,特别是在类的__init__()方法中,是一种极其糟糕的编程实践。 - martineau
@martineau 我必须承认,6年后我仍然没有完全掌握各种实践中的所有细节。您介意解释一下这种用法为什么不好吗?并不是说我完全不同意,只是想从根本上理解您所指出的问题。我甚至不再使用Python进行编程,我不希望旧习惯影响到我的其他项目。 - jtsmith1287
jtsmith:全局变量长期以来一直被认为是有很多缺点的,这些缺点与Python没有特别关联,但它们经常被使用,因为这使得代码更短。无论如何,在这种情况下,我认为可以通过将gems作为参数传递给Jewel的构造函数来轻松避免使用全局变量。所以我不认为在这个网站上有太多借口供那么多初学者程序员使用全局变量。 - martineau
@martineau,我理解你的意思,但是如何将gems作为参数传递给Jewel的构造方法呢? - Mitchell van Zuylen
1
@Mitchell:最简单的方法是将组显式地传递给“Jewel”子类初始化程序。然而,让任何类的实例将自己添加到某种组中听起来像是一种糟糕的设计(这可能会引诱您开始使用全局变量进行操作)。这就是为什么被接受的答案——在初始化程序之外将其添加到组中——确实可能是最好的原因。 - martineau

1

只需使用组列表调用超级__init__函数。例如:

def __init__(self):
    pygame.sprite.Sprite.__init__(self, self.groups)

然后,在您的层次结构的每个类中,您应该定义一个属性self.groups,而超级构造函数将完成将每个实例添加到其组的工作。在我看来,这是最干净的解决方案。否则,只需在每个类中显式调用带有组列表的超级构造函数即可。

0

更简单的方法是直接将精灵传递给构造函数:

gems = pygame.sprite.Group(gem1, gem2)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接