2
\$\begingroup\$

I want to use sprite groups in my game using pygame and the default draw isn't enough. I have tried some tutorials but I failed.

So, being more specific: I want to create custom methods for sprite groups in pygame such as .handle_event (this method can exist at all sprites or not).

\$\endgroup\$
1
\$\begingroup\$

You can create a pygame.sprite.Group subclass and add the methods you need. If you want to customize and override the draw method (which you can see here), you have to copy the original method and then add your modifications to it.

class ExtendedGroup(pygame.sprite.Group):

    def handle_event(self, event):
        for spr in self.sprites():
            # Check if the sprite has a `handle_event` method.
            if hasattr(spr, 'handle_event'):
               spr.handle_event(event)

    def draw(self, surface):
        sprites = self.sprites()
        surface_blit = surface.blit
        for spr in sprites:
            self.spritedict[spr] = surface_blit(spr.image, spr.rect)
            # I've added this line which draws a rect.
            pygame.draw.rect(surface, SIENNA, (spr.rect.topleft, (15, 15)))
        self.lostsprites = []
\$\endgroup\$
0
1
\$\begingroup\$

I keep track of sprite groups using attributes of my Game class, which contains my game loop.

For example, in the new_game() method of this class, I create groups in the following way:

    # create groups
    self.mobs = pg.sprite.Group()
    self.projectiles = pg.sprite.Group()
    self.portals = pg.sprite.Group()

Each of these groups corresponds a class I created which inherits from Pygame's Sprite class. For example, here is a sketch of my Mob class.

class Mob(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.mobs
        pg.sprite.Sprite.__init__(self, self.groups)     # this will add any instance of this class to the game's mobs group  
        self.game = game
        self.image = pg.Surface((64,64))            
        self.image.fill(RED)                            
        self.pos = vec(x,y)
        self.bounding_rect = pg.Rect((0,0),(64,64))     
        self.bounding_rect.center = self.pos

    def update():
        pass

    def draw():
        pass

Notice that in my initialization code, I add any instance of this class to my mobs group. Notice further that I allow myself to define update() and draw() methods for this class.

I do something similar with classes for projectiles, portals, etc. They all have their own group and can have their own update() and draw() methods.

If you structure things this way, you can then update and draw all your objects in your main game loop's update() and draw() methods like this:

def update(self):
   for mob in self.mobs:
       mob.update()
   for projectile in self.projectiles:
       projectile.update()
   ...

def draw(self):
   for mob in self.mobs:
       mob.draw()
   for projectile in self.projectiles:
       projectile.draw()
   ...

In this way, you can create custom update() and draw() methods for whatever objects your game requires.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you! I liked this idea. Howerver, the below answer is what I was looking for. \$\endgroup\$
    – CFLS
    Mar 9 '18 at 14:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .