Search code examples
pythonpygamespritedraw

How do I draw part of the sprite image using pygame spritegroups?


I want to draw a part of the sprite image to slowly reveal it. If I was handling the draw I would just do:

def draw(self, screen):
    screen.blit(self.image, self.rect, self.viewport)

and change the viewport size in the objects update method. I tried adding this to the code but it just shows the whole image. The update is definitely being called by the spritegroup update method and the viewport rect is being updated correctly, and in the game draw I have:

self.all_sprites.draw(screen)

How would I achieve this using pygame spritegroups? Also, none of the sprites have a draw method.


Solution

  • You can define a subsurface that is directly linked to the source surface with the method subsurface:

    subsurface(Rect) -> Surface

    Returns a new Surface that shares its pixels with its new parent. The new Surface is considered a child of the original. Modifications to either Surface pixels will effect each other.

    Create the subsurface either once in the constructor or continuously in an update method. e.g.:

    class SpriteObject(pygame.sprite.Sprite):
    
        def __init__(self, image):
            # [...]
    
            self.complete_image = image 
            
        def update(self):
            self.image = self.complete_image.subsurface(self.viewport)
    

    Now you don't need the draw method anymore and can use self.all_sprites.draw(screen), because the image attribute is a subsurface of the entire image. pygame.sprite.Group.draw() uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects.