PyGame:使用pygame.sprite.LayeredUpdates()

PyGame: use of pygame.sprite.LayeredUpdates()

我查看了文档并试图在网上找到示例,但我没有设法对精灵进行分层。以下是部分代码:

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self, self.groups)
        ...
        self.layer = 2
 
class Tree(pygame.sprite.Sprite):
    def __init__(self, screen_size, tree_id):
        pygame.sprite.Sprite.__init__(self, self.groups)
        ...
        self.layer = 1
    
    

pygame.init()
...

sprites = pygame.sprite.LayeredUpdates()
players = pygame.sprite.LayeredUpdates()
trees = pygame.sprite.LayeredUpdates()

Player.groups = sprites, players
Tree.groups = sprites, trees
...
    
mario = Player() 
nbtrees = 10
[Tree(size, x) for x in range(1,nbtrees+1)]


while 1:
    ...

    sprites.clear(screen,background)
    sprites.draw(screen)
    pygame.display.flip()

我删除了不相关的部分,事件处理,碰撞检测等等。问题是,它工作得非常好;例如,使用组 trees 的冲突管理进行得很顺利,这似乎表明这些组没问题。唯一的问题是:无论我在 PlayerTree 类 中为 self.layer 设置的值如何,树(所有树)总是在玩家上方闪烁。

documentation表示指定图层的几种方式,包括以下几种: “如果您添加的精灵有一个属性层,那么将使用该层。” 这正是我所做的,但没有成功。

请注意,我并没有真正将精灵“添加”到组中;我将这些组分配给我的精灵的 类,因为那是我以前对 pygame.sprite.Group() 所做的,这很方便并且通常都是一样的。我尝试使用群组的 add() 方法,但没有任何改变。

我想也许我没有正确初始化组,但奇怪的是一切正常,除了分层。我非常感谢一些工作示例。

我自己的一个程序也遇到了同样的问题。我不知道为什么,但是精灵组无法识别图层属性。我的解决方案是使用关键字参数将图层传递给 group.add() 方法,如下所示:

class player(pygame.sprite.Sprite):
    layer = 1
    def __init__ (self):
        pygame.sprire.Sprite.__init__(self)
        sprites.add(self, layer = self.layer)

为了方便,我喜欢在 init 方法中将精灵添加到组中。

我觉得没必要多组分层。一组画图更方便,一个LayeredUpdate组就可以搞定所有的层次。

我自己刚刚花了一些时间与 pygame.sprite.LayeredUpdates() 打交道。

我知道这已经很晚了,但是当我自己想弄清楚如何使用它时,我看到了这个 post。我解决了这个问题并想回答这个问题,希望能帮助下一个人。

精灵内部的属性必须命名为 self._layer 而不是 self.layer。请注意名称中的前导下划线。

这不是我所期望的,文档说 "If the sprite you add has an attribute layer then that layer will be used",它实际上并没有告诉您属性的正确名称,但似乎暗示它应该是 'layer',尽管它不是。

如果您使用 self._layer,精灵层将按预期工作,而无需通过 add() 调用传递它。

在您的代码中,您需要:

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self, self.groups)
        ...
        self._layer = 2

class Tree(pygame.sprite.Sprite):
    def __init__(self, screen_size, tree_id):
        pygame.sprite.Sprite.__init__(self, self.groups)
        ...
        self._layer = 1

它应该可以工作。

编辑:

我刚刚在 pygame.sprite.LayeredUpdates docs 中更正了这个问题,因此人们可能不再需要来这里寻找这个答案。

我进一步挖掘自己,意识到我没有试图让它以正确的方式工作。要知道的两件重要事情(我不知道)是:

  1. 图层只在同一组内工作。如果一组中的所有精灵都在同一层(例如您示例中的树),则该组不应是 LayeredUpdates() 对象,只需使用普通的 Group() 对象

  2. 必须在将精灵添加到 LayeredUpdates() 组之前设置属性“_layer”(这就是为什么上面的答案对我不起作用)。之后它是只读的,精灵的图层只能通过组的 change_layer() 方法更改。

请注意,change_layer() 方法必须用于 LayeredUpdates() 组,而不是精灵本身。

这是一个例子:

all_sprites = pygame.sprite.LayeredUpdates()
players = pygame.sprite.Group()
trees = pygame.sprite.Group()

class Tree(pygame.sprite.Sprite):
    def __init__(self):
        self._layer = 1
        pygame.sprite.Sprite.__init__(self, all_sprites, trees)
        # sprite has been added to all_sprites group with layer 1

class Player(pygame.sprite.Sprite):
    def __init__(self):
        self._layer = 2
        pygame.sprite.Sprite.__init__(self, all_sprites, players)
        # sprite has been added to all_sprites group with layer 2
        ...
        all_sprites.change_layer(self, 3)
        # sprite layer in all_sprites has been changed to 3

while True:
    all_sprites.clear(screen,background)
    all_sprites.draw(screen)
    pygame.display.flip()