Learning Goals
3 minBy the end of this lesson you can:
- Create an
Actorby giving it the name of an image file in theimages/folder. - Set an actor's position using
actor.posand callactor.draw()in thedraw()function. - Explain the folder structure Pygame Zero expects and find free sprite assets online.
Warm-Up · Names vs Strings
5 minActor("alien") loads images/alien.png. The name you pass must match the filename exactly. Predict what happens in each case below:
player = Actor("Alien") # A — capital A enemy = Actor("alien") # B — lowercase a boss = Actor("ALIEN") # C — all caps
Show the answer
Only B works (assuming the file is images/alien.png in lowercase). On Windows, file names are case-insensitive, so A and C might also work — but on Linux (including Raspberry Pi and many hosting servers) they would fail. Always use lowercase filenames and lowercase names in Actor().
New Concept · What Is an Actor?
12 minThink of an Actor like a sticker sheet. You pick the sticker you want (the image file), peel it off and place it anywhere on the canvas. You can reposition it, rotate it, or swap it for a different sticker at any time.
Creating an Actor
player = Actor("alien") # loads images/alien.png
The string you pass is the image name without the extension. Pygame Zero looks inside an images/ folder next to your script.
Folder structure
my_game/
├── game.py ← your script
└── images/
└── alien.png ← actor image (lowercase filename)Positioning the Actor
player.pos = (300, 200) # centre of a 600x400 window
actor.pos sets the centre of the image. You can also use actor.x and actor.y separately, or anchors like actor.topleft and actor.center.
Drawing the Actor
def draw(): screen.fill("midnightblue") player.draw() # paints the image at actor.pos
Where to find free sprites
No image of your own yet? Two great free sources:
- kenney.nl — thousands of free game assets in neat packs (spaceships, characters, tiles). Download a pack and drop a
.pnginto yourimages/folder. - opengameart.org — community-contributed art, many CC0 licensed (no attribution needed for student projects).
While you look for a good image, use a coloured rectangle as a stand-in (see the worked example below).
Worked Example · A Sprite on the Canvas
12 minThe story
Arjun downloaded the Kenney "Space Shooter" pack and saved playerShip1_blue.png as images/ship.png (renamed to lowercase). Save the script as sprite_demo.py:
# sprite_demo.py — load and display an Actor import pgzrun WIDTH = 600 HEIGHT = 400 TITLE = "Sprite Demo" ship = Actor("ship") # loads images/ship.png ship.pos = (300, 200) # place in the window centre def draw(): screen.fill("midnightblue") ship.draw() # paint the sprite at ship.pos screen.draw.text( "(" + str(ship.x) + ", " + str(ship.y) + ")", center=(300, 360), fontsize=20, color="lightgrey", ) pgzrun.go()
No image file yet? Use this stand-in
If you don't have an image ready, skip the Actor and draw a rectangle as a placeholder. It behaves the same when you add movement later:
# stand-in version — no image file needed import pgzrun WIDTH = 600 HEIGHT = 400 TITLE = "Stand-in Sprite" ship_x = 300 ship_y = 200 def draw(): screen.fill("midnightblue") screen.draw.filled_rect(Rect((ship_x - 20, ship_y - 15), (40, 30)), "deepskyblue") screen.draw.text("ship", center=(ship_x, ship_y + 26), fontsize=16, color="lightgrey") pgzrun.go()
What you'll see
Try It Yourself
13 minAfter creating your Actor, change its pos to three different positions — one near the top-left, one near the top-right, and one at the bottom centre — by editing the line directly. See how the sprite jumps around the canvas.
Hint
ship.pos = (60, 60) # near top-left ship.pos = (540, 60) # near top-right ship.pos = (300, 360) # bottom centre
Create a second Actor with a different image (or use a second stand-in rectangle with a different colour). Position both Actors on screen at the same time — they should both appear when you run the script.
Hint
ship = Actor("ship") ship.pos = (150, 200) enemy = Actor("enemy") # needs images/enemy.png enemy.pos = (450, 200) def draw(): screen.fill("midnightblue") ship.draw() enemy.draw()
Mini-Challenge 🔥 · Buggy Actor Parade
8 minImran tried to put three actors in a row using a list but got an AttributeError and nothing draws. Find and fix the bugs.
# imran_parade.py — buggy
import pgzrun
WIDTH = 600
HEIGHT = 400
actors = [
Actor("ship", pos=(100, 200)),
Actor("ship", pos=(300, 200)),
Actor("ship", pos=(500, 200)),
]
def draw():
screen.fill("black")
for a in actors:
a.Draw() # bug 1: wrong capitalisation
def update():
for a in actors:
a.x = a.x + 1 # bug 2: floats-only .x — should be fine
if a.x > WIDTH + 50:
a.x = -50 # wrap around — this line is actually OK
pgzrun.go()It works if…
three ship sprites drift from left to right and reappear on the left
Show the fix
# imran_parade.py — fixed import pgzrun WIDTH = 600 HEIGHT = 400 actors = [ Actor("ship", pos=(100, 200)), Actor("ship", pos=(300, 200)), Actor("ship", pos=(500, 200)), ] def draw(): screen.fill("black") for a in actors: a.draw() # bug 1 fixed: draw() is lowercase def update(): for a in actors: a.x = a.x + 1 if a.x > WIDTH + 50: a.x = -50 pgzrun.go()
The only real bug was a.Draw() with a capital D. Actor's method is lowercase draw(), matching all other Pygame Zero hooks. The update() logic was actually correct.
Recap
3 minAn Actor links a variable in your script to a .png image file in the images/ folder next to your script. Use actor.pos = (x, y) to place it and actor.draw() inside draw() to paint it. File names and the string you pass to Actor() must be lowercase and match exactly. For free art, try kenney.nl or opengameart.org.
Vocabulary Card
- Actor
- A Pygame Zero object that wraps an image file and tracks position, size, and rotation for you.
- images/ folder
- The directory next to your script where Pygame Zero looks for sprite images. Files must be lowercase
.png. - actor.pos
- A tuple
(x, y)giving the centre of the actor on screen. Set it to move the sprite. - actor.draw()
- Paints the actor's image at its current position. Call it inside your
draw()function.
Homework
4 minDownload a free sprite from kenney.nl (try the "Simplified Platformer Pack" or "Space Shooter Redux"). Save one image as a lowercase .png in your images/ folder. Write a script that places the Actor at the window's centre and displays its coordinates below it. Save as my_sprite.py and bring a screenshot to the next class.
Stretch. Place three copies of the same Actor at three different positions using a list and a for loop in draw().
Sample · my_sprite.py
# my_sprite.py — display a downloaded sprite and its coordinates import pgzrun WIDTH = 600 HEIGHT = 400 TITLE = "My First Sprite" hero = Actor("hero") # images/hero.png — your downloaded and renamed image hero.pos = (WIDTH // 2, HEIGHT // 2) def draw(): screen.fill("midnightblue") hero.draw() screen.draw.text( "pos: (" + str(hero.x) + ", " + str(hero.y) + ")", center=(WIDTH // 2, hero.y + 60), fontsize=20, color="white", ) pgzrun.go()
Your image name will differ. What matters: lowercase filename, Actor name matches the file, actor.draw() called inside draw().