In this tutorial, we will learn how to animate a character in Python using the Pygame library and a spritesheet. Instead of loading lots of separate images to animate our main sprite/character, we will use one single image containing multiple frames — a much more efficient and professional approach used in real games!
Our learning objectives are as follows:
- Understand what a spritesheet is
- Load and display images in Pygame
- Extract frames from a spritesheet
- Animate a walking character
What’s a Spritesheet?
A spritesheet is a single image that contains multiple frames to be used to create a frame-based animation.
For example: a walking character might have 6 frames showing different leg and arm positions.
Instead of loading 6 separate images, we:
- Load one image (called a spritesheet)
- “Cut” it into smaller pieces (frames)
- Display these frames in sequence
Here is a spritesheet to create an animated walking ninja girl. Our animation will contain 9 frames:
![]()
When we animated these frames in sequence we will get the following animation:

Let’s now investigate the Python code to complete this animation with a 2D game implemented using the Pygame library.
Python Tutorial
Step 1: Setup the game (using Pygame)
You will need to make sure that the Pygame library is already installed on your computer.
The you will create your main python file and use the following code to initialise your game:
import pygame
import sys
pygame.init()
# Create game window
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Spritesheet Animation")
Step 2: Loading the Spritesheet
You will need to download the spritesheet below and save it in the same folder as where your Python file is saved.
![]()
Now add the following line of code to load the spritesheet file:
spritesheet = pygame.image.load("character_spritesheet.png").convert_alpha()
Step 3: Extracting Frames from the Spritesheet
We will use the following function to extract the different frames from the spritesheet: (Add this function at the top of your code)
def load_frames(sheet, x, y, frame_width, frame_height, num_frames):
frames = []
for i in range(num_frames):
frame = sheet.subsurface(
pygame.Rect(x + i * frame_width, y, frame_width, frame_height)
)
frames.append(frame)
return frames
After loading the spritesheet, we will call our function. For instance to extract the top row of frames (running animation) we will start extraxcting 9 frames from position x=0 and y=0, each frame being 120 pixels wide and 160 pixels high.
Here the code we will use to extract these 9 frames:
frames = load_frames(spritesheet, 0, 0, 120, 160, 9)
We will also use two animation variables as follows:
current_frame = 0 animation_speed = 0.15
Step 4: Animating our character
Now let’s add some code to the main program loop of our game:
clock = pygame.time.Clock()
carryOn = True
while carryOn:
screen.fill((30, 30, 30))
# Handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Update animation
current_frame += animation_speed
if current_frame >= len(frames):
current_frame = 0
# Draw current frame
screen.blit(frames[int(current_frame)], (100, 300))
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Your Turn
Use the above code and spritesheet to reproduce the animation of the ninja-girl running.
The tweak the code provided to make a jumping ninja girl animation.
Finally, create one more animation of the ninja girl attacking!

Using Object Oriented Programming
Within a Pygame project, it is very likely that you will define a separate class for the main character of your game. So let’s rework the code provided above to create a NinjaGirl class. We will then respond to keyboards input to change the state of our player (e.g. from idle to running or attacking). We will also use some code to flip our character so that we can have them looking/running right or left.
When trying the code provided below use the following keyboard inputs:
- Right arrow to run towards the right
- Left arrow to run towards the left
- Space bar to attack
Python Code: Main.py file
# Ninja Girl Animation using Pygame - www.101computing.net/pygame-animations-using-a-spritesheet/
import pygame
import sys
from ninja_girl import NinjaGirl
IDLE = 0
RUN = 1
JUMP = 2
ATTACK = 3
DEAD = 4
pygame.init()
# Create game window
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Spritesheet Animation")
# Create sprite
player = NinjaGirl(100, 300)
all_sprites = pygame.sprite.Group(player)
clock = pygame.time.Clock()
running = True
while running:
screen.fill((30, 30, 30))
# Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
# State logic
if keys[pygame.K_RIGHT]:
player.set_state(RUN)
player.rect.x += 3
player.facing_right = True
elif keys[pygame.K_LEFT]:
player.set_state(RUN)
player.rect.x -= 3
player.facing_right = False
elif keys[pygame.K_SPACE]:
player.set_state(ATTACK)
else:
player.set_state(IDLE)
# Update + draw
all_sprites.update()
all_sprites.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Python Code: ninja_girl.py file
import pygame
IDLE = 0
RUN = 1
JUMP = 2
ATTACK = 3
DEAD = 4
class NinjaGirl(pygame.sprite.Sprite):
#This class represents a ball. It derives from the "Sprite" class in Pygame.
def __init__(self, x, y):
super().__init__()
# State
self.state = IDLE
self.facing_right = True
# Animation
self.animations = {}
self.current_frame = 0
self.animation_speed = 0.15
# Load spritesheets
self.load_animations()
# Starting image
self.image = self.animations[self.state][0]
self.rect = self.image.get_rect()
# Position
self.rect.x = x
self.rect.y = y
def load_frames(self, filename, x, y, frame_width, frame_height, num_frames):
sheet = pygame.image.load(filename).convert_alpha()
frames = []
for i in range(num_frames):
frame = sheet.subsurface(
pygame.Rect(x + i * frame_width, y, frame_width, frame_height)
)
frames.append(frame)
return frames
def load_animations(self):
self.animations[IDLE] = self.load_frames("spritesheet-ninja-girl.png", 960, 350, 120, 160, 1)
self.animations[RUN] = self.load_frames("spritesheet-ninja-girl.png", 0, 0, 120, 160, 9)
self.animations[JUMP] = self.load_frames("spritesheet-ninja-girl.png", 0, 160, 120, 160, 9)
self.animations[ATTACK] = self.load_frames("spritesheet-ninja-girl.png", 0, 350, 200, 160, 4)
self.animations[DEAD] = self.load_frames("spritesheet-ninja-girl.png", 800, 350, 200, 160, 1)
def update(self):
frames = self.animations[self.state]
self.current_frame += self.animation_speed
if self.current_frame >= len(frames):
self.current_frame = 0
frame = frames[int(self.current_frame)]
# Flip image if facing left
if not self.facing_right:
frame = pygame.transform.flip(frame, True, False)
self.image = frame
def set_state(self, new_state):
if self.state != new_state:
self.state = new_state
self.current_frame = 0 # Reset animation

Solution...
The solution for this challenge is available to full members!Find out how to become a member:
➤ Members' Area






