Animation with Pygame

Let’s animate some png files

Let’s say we got a bunch of files like these you can see below:

Whit pygame you can animate them and have something like this walking pumpkin guy that you can see in the following video:

Let’s check out how to do this with Python and the module pygame.

The sprites can be downloaded here.

I took the code from here.

I modified it a little bit to make it more compact and to avoid error messages at the end and the result was this.

import pygame
import glob
 
SIZE = WIDTH, HEIGHT = 150, 200 #the width and height of our screen
FPS = 20 #Frames per second

This are just size and frame per seconds (higher value = higher speed).

The sprite class

Here is the main change that I made to the original code.

self.images = [pygame.image.load(img) for img in glob.glob("images\\*.png")]

This is a list comprehension, a way to write a loop in python. We could have done the same stuff with this:

list_of_png = glob.glob("images\\*.png") # a list with all png files in images folder
for image in list_of_png:
   pygame.image.load(image)

The original code that the one I made above was like this:

        self.images = []
        self.images.append(pygame.image.load('images/walk1.png'))
        self.images.append(pygame.image.load('images/walk2.png'))
        self.images.append(pygame.image.load('images/walk3.png'))
        self.images.append(pygame.image.load('images/walk4.png'))
        self.images.append(pygame.image.load('images/walk5.png'))
        self.images.append(pygame.image.load('images/walk6.png'))
        self.images.append(pygame.image.load('images/walk7.png'))
        self.images.append(pygame.image.load('images/walk8.png'))
        self.images.append(pygame.image.load('images/walk9.png'))
        self.images.append(pygame.image.load('images/walk10.png'))

As you can see, in one like I made the work that was done here with 11 line. I had to change the name of the files to walk0.png1, walk02.png… with a 0 before the one digit numbers, because otherwise the code would put walk10.png after walk1.png.

There is just one porblem with my code. In the list_of_png the walk10.png goes after the walk1.png, instead of being the last one of the list. There are several way to fix this and it’s left to your imagination, but I posted a solution in this post that you can read (How to put a list of images in order) to see how I do it.

Another way to do that is to change the name of the files. It will be explained in the next paragraph.

How to change the name of the files

The previous method makes you have the right sequence of images without changing the names of the files.

If,  istead, you want fix the problem of the walk10.png after the walk1.png changing the names of the files and you do not want to change every file name manually, see in this video how I do:

class MySprite(pygame.sprite.Sprite):
    def __init__(self):
        super(MySprite, self).__init__()
 
        self.images = [pygame.image.load(img) for img in glob.glob("images\\*.png")]
        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

In this class we load the images and the update method makes the self.image be changed every frame that is called in the while loop below:

def main():
    pygame.init()
    screen = pygame.display.set_mode(SIZE)
    pygame.display.set_caption("Trace")
    my_sprite = MySprite()
    my_group = pygame.sprite.Group(my_sprite)
    clock = pygame.time.Clock()

After initialized, created the screen surface, title, loaded the sprites, added them to a Group and istanciated the Clock, comes the loop:

    loop = 1
    while loop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                loop = 0
 
        my_group.update()
        screen.fill((0,0,0))
        my_group.draw(screen)
        pygame.display.update()
        clock.tick(FPS)
    pygame.quit()

Here (if you quit the window closes) you update the frame of sprite, clear the screen with black to avoid leaving traces on the screen, draw the sprite, update the screen at a certain frame rate.

When you click the quit button pygame quits.

The whole code:

import pygame
import glob
 
SIZE = WIDTH, HEIGHT = 150, 200 #the width and height of our screen
FPS = 20 #Frames per second
 
class MySprite(pygame.sprite.Sprite):
    def __init__(self):
        super(MySprite, self).__init__()
 
        self.images = [pygame.image.load(img) for img in glob.glob("images\\*.png")]
        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 main():
    pygame.init()
    screen = pygame.display.set_mode(SIZE)
    pygame.display.set_caption("Trace")
    my_sprite = MySprite()
    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
 
        my_group.update()
        screen.fill((0,0,0))
        my_group.draw(screen)
        pygame.display.update()
        clock.tick(FPS)
    pygame.quit()
 
if __name__ == '__main__':
    main()

Go to the next episode

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.