3

i am trying to make an animation of when my player gets shot to make it seem like he is falling to the ground.

i have tried the code below but that doesn't seem to work. it slows down the frames and only shows the last image of my animation is there a simpler way of animation in pygame?

    if player2_hit_sequence == True:
        stage1 = True
        if stage1 == True:
            game_display.blit(dying1_p2, (player2X, player2Y))
            time.sleep(0.2)
            stage1 = False
            stage2 = True
        if stage2 == True:
            game_display.blit(dying2_p2, (player2X, player2Y))
            time.sleep(0.2)
            stage2 = False
            stage3 = True
        if stage3 == True:
            game_display.blit(dying3_p2, (player2X, player2Y))
            time.sleep(0.2)

is there a function to make a sequence of images or something like that?

BOBTHEBUILDER
  • 345
  • 1
  • 4
  • 20

1 Answers1

2

Ok so for animation you need a bunch of images, and a timer.

I'm presenting some code snippets based around a pygame sprite. Maybe this doesn't exactly fit the question, but it seems like a better solution then painting/blitting images manually.

So first the code starts with a sprite class:

class AlienSprite(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.base_image = pygame.image.load('alien.png').convert_alpha()
        self.image = self.base_image
        self.rect = self.image.get_rect()
        self.rect.center = ( WINDOW_WIDTH//2, WINDOW_HEIGHT//2 )
        # Load warp animation
        self.warp_at_time = 0
        self.warp_images = []
        for filename in [ "warp1.png", "warp2.png", "warp3.png" ]:
            self.warp_images.append( pygame.image.load(filename).convert_alpha() )

So the idea is the Alien Sprite has a "normal" image, but then when it "warps" (teleports) an animation plays. The way this is implemented is to have a list of animation images. When the animation starts, the sprite's image is changed from base_image to the first of the warp_images[]. As time elapses, the sprites image is changed to the next frame, and then the next, before finally reverting back to the base image. By embedding all this into the sprite update() function, the normal updating mechanism for sprites handles the current "state" of the alien sprite, normal or "warp". Once the "warp"-state is triggered, it runs without any extra involvement of the pygame main loop.

def update(self):
    # Get the current time in milliseconds (normally I keep this in a global)
    NOW_MS = int(time.time() * 1000.0)
    # Did the alien warp? (and at what time)
    if (self.warp_at_time > 0):
        # 3 Frames of warp animation, show each for 200m
        ms_since_warp_start = NOW_MS - self.warp_at_time
        if ( ms_since_warp > 600 ):
            # Warp complete
            self.warp_at_time = 0
            self.image = self.base_image  # return to original bitmap
            # Move to random location
            self.rect.center = ( random.randrange( 0, WINDOW_WIDTH ), random.randrange( 0,  WINDOW_HEIGHT ) )
        else:
            image_number = ms_since_warp // 200  # select the frame for this 200ms period
            self.image = self.warp_images[image_number] # show that image

def startWarp(self):
    # Get the current time in milliseconds (normally I keep this in a global)
    NOW_MS = int(time.time() * 1000.0)
    # if not warping already ...
    if (self.warp_at_time == 0):
        self.warp_at_time = NOW_MS

So the first thing to notice, is that the update() uses the clock to know the number of elapsed milliseconds since the animation started. To keep track of the time I typically set a global NOW_MS in the game loop.

In the sprite, we have 3 frames of animation, with 200 milliseconds between each frame. To start a sprite animating, simply call startWarp() which obviously just kicks-off the timer.

SPRITES = pygame.sprite.Group()
alien_sprite = AlienSprite()
SPRITES.add(alien_sprite)

...

# Game Loop
done = False
while not done:
    SPRITES.update()

    # redraw window
    screen.fill(BLACK)
    SPRITES.draw(screen)
    pygame.display.update()
    pygame.display.flip()

    if (<some condition>):
        alien_sprite.startWarp()  # do it

Obviously all those frame timings & what-not should be member variables of the sprite class, but I didn't do that to keep the example simple.

Kingsley
  • 14,398
  • 5
  • 31
  • 53