Menu

Pygame Animation: Frames and Sprite Sheets

Animate characters in pygame: swap between frames on a timer, cut frames out of a sprite sheet with subsurface, play a different animation when walking, and run one-off effects such as explosions.

This page includes runnable editors. Edit, run, and see output instantly.

Animation in pygame is a flip book: you keep a few images of the same character in slightly different poses and show a different one every few frames.

Two frames

The simplest animation alternates two images. This bat flaps by switching between bat.png and bat_flap.png every 8 frames:

(tick // 8) % len(frames) counts 0, 0, 0 ... 1, 1, 1 ... 0 again: the number 8 is the speed, smaller is faster.

Sprite sheets

Art often comes as one sprite sheet: every frame on a grid in a single image. Load it once and cut frames with subsurface, which makes a Surface that shares the sheet's pixels:

(216, 72)

The whole sheet is drawn small in the corner, and the first two tiles of its top row play as a walk at 4 times their size. This sheet is a grid of 24 by 24 tiles, so the tile in column c and row r starts at (c * 24, r * 24). Changing frames by time (get_ticks, every 150 ms) keeps the animation speed the same at any frame rate.

Walk and idle

A character usually has several animations and picks one by what it is doing. An animated sprite keeps the lists and switches between them:

Press Play, click the game and walk with Left and Right. A float frame that grows by 0.15 a game frame changes the picture about every 7 frames; int(self.frame) picks the image.

One-shot effects

An explosion plays its frames once and then removes itself:

Click anywhere in the game to set off an explosion. self.kill() takes the sprite out of its group after the last frame.

Frequently Asked Questions

How do I animate a sprite in pygame?

Keep a list of frame images and an index. Every few game frames (or every so many milliseconds), move to the next index and set the sprite's image to that frame.

How do I use a sprite sheet in pygame?

Load the sheet once, then cut each frame with sheet.subsurface((x, y, width, height)). For a grid of equal tiles, the frame in column c and row r starts at (c * w, r * h).

How do I make an animation independent of the frame rate?

Change frames by time, not by loop count: store the time of the last change from pygame.time.get_ticks(), and advance when 100 or so milliseconds have passed.

Coddy programming languages illustration

Learn to code with Coddy

Get started