Pygame Sprite Animation update

With this code you can animate this png files (go here to download them).

How to animate in different actions a sprite in pygame. It could seem a little tricky, but with the help of a class and the superclass Sprite and the Group class, we can manage the animation quite nicely with Python and Pygame, in this episode of the serie for the making of a platform game in Python…

Put the extracted images in a folder called “png” in the folder where this code is.

Right order of the images

As the images that ends with 10, 11, 12 ecc. would be positioned after image 1 and before image 2, I used this ‘trick’ to load the images from 1 to 9 first, then images 10 to… in a second list, so that they were displayed in the right sequence, with this code:

        im = glob.glob(f"png\\{action}*.png")
        lenim = len(im[0])
        self.images = [pygame.image.load(img) for img in glob.glob(f"png\\{action}*.png") if len(img) == lenim]
        self.images2 = [pygame.image.load(img) for img in glob.glob(f"png\\{action}*.png") if len(img) > lenim]
        self.images.extend(self.images2)

As you can see, I get the lenght of the first image (the one with the number 1) that is shorter than the ones with 10, 11… in the name. So I load these first and then the ones with the longer names. At the end I join them in one list of images with extend.

The whole code

import pygame
import glob
 
SIZE = WIDTH, HEIGHT = 600, 600 #the width and height of our screen
FPS = 20 #Frames per second
 
class MySprite(pygame.sprite.Sprite):
    def __init__(self, action):
        super(MySprite, self).__init__()
        im = glob.glob(f"png\\{action}*.png")
        lenim = len(im[0])
        self.images = [pygame.image.load(img) for img in glob.glob(f"png\\{action}*.png") if len(img) == lenim]
        self.images2 = [pygame.image.load(img) for img in glob.glob(f"png\\{action}*.png") if len(img) > lenim]
        self.images.extend(self.images2)
        self.index = 0
        self.rect = pygame.Rect(5, 5, 150, 198)

    def update(self):
        if self.index >= len(self.images):
            self.index = 0
        self.image = self.images[self.index]
        self.index += 1

def action(action):
    my_sprite = MySprite(action)
    my_group = pygame.sprite.Group(my_sprite)
    return my_group

def main():
    pygame.init()
    screen = pygame.display.set_mode(SIZE)
    pygame.display.set_caption("Press i w r j d or arrows and space")
    my_sprite = MySprite("idle")
    my_group = pygame.sprite.Group(my_sprite)
    clock = pygame.time.Clock()
    loop = 1
    while loop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w or event.key == pygame.K_LEFT:
                    my_group = action("walk")
                if event.key == pygame.K_d:
                    my_group = action("dead")                
                if event.key == pygame.K_j or event.key == pygame.K_UP:
                    my_group = action("jump")
                if event.key == pygame.K_i or event.key == pygame.K_SPACE:
                    my_group = action("idle")
                if event.key == pygame.K_r or event.key == pygame.K_RIGHT:
                    my_group = action("run")
                if event.key == pygame.K_d or event.key == pygame.K_DOWN:
                    my_group = action("dead")

 
        my_group.update()
        screen.fill((0,0,0))
        my_group.draw(screen)
        pygame.display.update()
        clock.tick(FPS)
    pygame.quit()
 
if __name__ == '__main__':
    main()

Live coding video about sprite animation in Pygame

A more efficient code… Use this one…

If you want to use the code to animate a sprite in a real game, you better use the following code:

This is the code

import pygame
import glob
 
SIZE = WIDTH, HEIGHT = 600, 600 #the width and height of our screen
FPS = 60 #Frames per second
 
def fps():
    fr = "V. 2 Fps: " + str(int(clock.get_fps()))
    frt = font.render(fr, 1, pygame.Color("coral"))
    return frt

class MySprite(pygame.sprite.Sprite):
    def __init__(self, action):
        super(MySprite, self).__init__()
        im = glob.glob(f"png\\{action}*.png")
        lenim = len(im[0])
        self.images = [pygame.image.load(img) for img in glob.glob(f"png\\{action}*.png") if len(img) == lenim]
        self.images2 = [pygame.image.load(img) for img in glob.glob(f"png\\{action}*.png") if len(img) > lenim]
        self.images.extend(self.images2)
        self.index = 0
        self.rect = pygame.Rect(5, 5, 150, 198)

    def update(self):
        if self.index >= len(self.images):
            self.index = 0
        self.image = self.images[self.index]
        self.index += 1

def create_sprites():
    idle = pygame.sprite.Group(MySprite("idle"))
    walk = pygame.sprite.Group(MySprite("walk"))
    run = pygame.sprite.Group(MySprite("run"))
    jump = pygame.sprite.Group(MySprite("jump"))
    dead = pygame.sprite.Group(MySprite("dead"))
    return idle, walk, run, jump, dead

def main():
    global clock
    global font

    pygame.init()
    font = pygame.font.SysFont("Arial", 60)
    screen = pygame.display.set_mode(SIZE)
    pygame.display.set_caption("Game v.2")
    idle, walk, run, jump, dead = create_sprites()
    my_group = idle
    clock = pygame.time.Clock()
    loop = 1
    while loop:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT: my_group = walk
                if event.key == pygame.K_d: my_group = dead                
                if event.key == pygame.K_UP: my_group = jump
                if event.key == pygame.K_SPACE: my_group = idle
                if event.key == pygame.K_RIGHT: my_group = run
                if event.key == pygame.K_DOWN: my_group = dead

 
        my_group.update()
        screen.fill((0,0,0))
        my_group.draw(screen)
        screen.blit(fps(), (10, 0))
        pygame.display.update()
        clock.tick(FPS)
    pygame.quit()
 
if __name__ == '__main__':
    main()

The video that shows wich code is better for animation (fps)

Pygame's Platform Game

Other Pygame's posts