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

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.