How to make a pygame sprite group move?

2019-08-02 17:11发布

问题:

I made a pygame.sprite.group for my enemies. I can display them on the screen, but I don't know how to make them all move? I want to have them pacing back and forth on the platforms (like left and right constantly). I know how to work with the movements of one sprite, but not a bunch in a group.

Here is what I have right now:

class Platform(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('levoneplatform.png')
        self.rect = self.image.get_rect()

class Enemy(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('enemy.png')
        self.rect = self.image.get_rect()

class LevOne():
    def __init__(self):

        self.background_image = pygame.image.load('night.png').convert_alpha()


        platforms_one = [ (200,300),
                        (50,500),
                        (550,650),
                        (300,200),
                        (120,100)
                   ]
        for k,v in platforms_one:
            platform = Platform()
            enemy = Enemy()
            platform.rect.x = k
            enemy.rect.x = k
            platform.rect.y = v
            enemy.rect.y = v - 44
            platform_list.add(platform)
            enemy_list.add(enemy)

    def update(self):
         screen.blit(self.background_image, [0, 0])

screen = pygame.display.set_mode((800,600))
enemy_list = pygame.sprite.Group()
platform_list = pygame.sprite.Group()

The rest is basically like my state changes and updates. I don't know how to move the entire sprite group. I know how to move one sprite, but not a bunch of sprites in one list.

回答1:

I would introduce 2 new attributes to your Enemy class: dx and platform. dx being the current speed in the x direction and platform being the platform the enemy is on. You'll have to pass the platform as an argument to your enemy object, which shouldn't be a problem (just pass it in when creating the platform and the enemy). Your Enemy class will now look like this:

class Enemy(pygame.sprite.Sprite):

    def __init__(self, platform):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('enemy.png')
        self.rect = self.image.get_rect()
        self.dx = 1  # Or whatever speed you want you enemies to walk in.
        self.platform = platform

Since your enemies inherit pygame.sprite.Sprite you could overwrite the update() method with something like this:

class Enemy(pygame.sprite.Sprite):

    def __init__(self, platform):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('enemy.png')
        self.rect = self.image.get_rect()
        self.dx = 1  # Or whatever speed you want you enemies to walk in.
        self.platform = platform

    def update(self):
        # Makes the enemy move in the x direction.
        self.rect.move(self.dx, 0)

        # If the enemy is outside of the platform, make it go the other way.
        if self.rect.left > self.platform.rect.right or self.rect.right < self.platform.rect.left:
                self.dx *= -1

What you can do now is just call the sprite group enemy_list.update() in your game loop which will call the update method of all your enemies, making them move.

I don't know how the rest of your project look like but this should work considering the code you've provided. What you could do later on is passing the time in the update method, making it so your enemies doesn't move based on the fps but rather by time. The pygame.sprite.Group.update() method takes any arguments as long as all objects in that group have an update method with the same arguments.

For more information, check out this talk or read the pygame docs.