Search code examples
pythonpygamepygame-surface

Scaling a sprite in main loop


I want to create a game where circles are generated randomly over the surface and start to grow. When 2 circles touch each other the game ends. So, everything is working except the resizing of the sprite during a loop. When I use transform.scale I get something like this:

Resizing using "transform.scale

Then I found transform.smoothscale in the doc. I used changed my code to use this and then it looked like this:

Resizing using "transform.smoothscale"

I also tried to use Rect.inflate but this did nothing to my sprite. And I tried Rect.infalte_ip and if I use this, the sprite won't grow it is more likely to move out of the frame. Any ideas on how I can make these Sprite grow in place and that they resize how they should?

class Bubbles(pygame.sprite.Sprite):
def __init__(self):
    super().__init__()
    self.image_scale = 100
    self.image_scale_factor = 1
    self.image = resources.BUBBLE_SKIN[0].convert_alpha()
    self.image = pygame.transform.scale(self.image, (self.image_scale, self.image_scale))
    self.rect = self.image.get_rect()
    self.rect.centerx = (random.randrange(Settings.object_range_limit + (self.image_scale//2), (Settings.width - Settings.object_range_limit - self.image_scale)))
    self.rect.centery = (random.randrange(Settings.object_range_limit + (self.image_scale//2), (Settings.height - Settings.object_range_limit - self.image_scale)))

    self.growth_rate = random.randint(1, 4)

def update(self):
    self.image_scale += self.growth_rate
    self.image = pygame.transform.scale(self.image, (self.image_scale, self.image_scale))

Solution

  • You must scale the original sprite, instead of gradually scaling the sprite. Every time you scale the sprint, the quality degrades. If you scale the sprite gradually, the quality gets worse and worse. Store the sprite to an attribute orignal_image and scale the orignal_image.

    If you want to scale the image by the center of the image, you must update the rect attribute after scaling the image with the new image size.
    See How do I scale a PyGame image (Surface) with respect to its center?

    class Bubbles(pygame.sprite.Sprite):
        def __init__(self):
            # [...]
        
            self.image = resources.BUBBLE_SKIN[0].convert_alpha()
            self.image = pygame.transform.scale(
                self.image, (self.image_scale, self.image_scale))
    
            self.original_image =  self.image
    
        def update(self):
            self.image_scale += self.growth_rate
            self.image = pygame.transform.scale(
                self.original_image, (self.image_scale, self.image_scale))
    
            self.rect = self.image.get_rect(center = self.rect.center)