43 The Power of Imagery: Loading and Using Sprites
In our previous lessons, we explored Pyxel’s game loop, coordinate system, and drawing primitives. Today, we’ll take our first step into working with pre-made images by learning how to load and display sprites in our games.
43.1 What are Sprites and Why Do We Need Them?
In game development, a sprite is a 2D image that represents a character, object, or environment element in your game. Sprites are essentially the digital actors and props on your game’s stage.
While we could draw everything using primitives (as we learned in our last lesson), this has several limitations:
- Time-consuming: Drawing complex characters or objects with primitives is tedious and repetitive
- Performance: Redrawing complex shapes every frame can be inefficient
- Detail: Primitives limit the level of detail you can achieve in your visuals
Sprites solve these problems by letting us pre-create our visual elements once and then simply place them in our game world as needed. This is much like how a puppeteer creates detailed puppets ahead of time, rather than crafting new ones during each performance.
43.2 The Pyxel Image Bank: Your Sprite Storage
Pyxel provides a structure called the image bank to store your game’s sprites and images. Think of it as a magical art gallery where your game’s visual elements are kept ready for use.
The image bank consists of several pages (numbered 0-2), each with a resolution of 256x256 pixels. Each page can store multiple sprites that you can reference in your game.
Here’s how the image bank is structured:
pyxel.images[0] # First image bank page (0)
pyxel.images[1] # Second image bank page (1)
pyxel.images[2] # Third image bank page (2)
43.3 Loading Images: Two Simple Methods
Before we can display sprites in our game, we need to load them into the image bank. Pyxel gives us two primary ways to do this:
43.3.1 Method 1: Loading an External Image File
You can load PNG files directly into Pyxel’s image bank:
import pyxel
160, 120, title="Sprite Example")
pyxel.init(# Load an image file into image bank 0 at position (0,0)
0].load(0, 0, "character.png") pyxel.images[
This code loads a PNG file named “character.png” into the first image bank (0) at the top-left position (0,0). The image will occupy the corresponding space in the image bank based on its dimensions.
43.3.2 Method 2: Using the Pyxel Editor
Pyxel includes a built-in editor that lets you create sprite art directly. To open it:
import pyxel
# Open the Pyxel editor
pyxel.editor()
or in the terminal:
py -m pyxel edit
This launches the Pyxel editor, where you can create and edit sprites, then save them in a resource file (.pyxres) to load in your game:
import pyxel
160, 120, title="Sprite Example")
pyxel.init(# Load resources from a .pyxres file
"game_resources.pyxres") pyxel.load(
43.4 Displaying Sprites with blt()
Once you have sprites in your image bank, you can display them in your game using the blt()
function, which stands for “block transfer”:
pyxel.blt(x, y, img, u, v, w, h, [colkey])
Let’s break down these important parameters:
x, y
: Where to draw the sprite on the screenimg
: Which image bank to use (0-2)u, v
: The top-left position of the sprite in the image bankw, h
: The width and height of the sprite to drawcolkey
(optional): The color to treat as transparent (defaults to None)
Here’s a simple example that displays a sprite at the center of the screen:
import pyxel
class SimpleSprite:
def __init__(self):
160, 120, title="Simple Sprite")
pyxel.init(# We're assuming there's already an 8x8 sprite at position (0,0) in image bank 0
self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw the sprite at the center of the screen
# Parameters: x, y, img_bank, sprite_x, sprite_y, width, height, transparent_color
76, 56, 0, 0, 0, 8, 8, 0)
pyxel.blt(
# Display instructions
5, 5, "Press Q to quit", 7)
pyxel.text(
SimpleSprite()
In this example:
- We display the sprite from image bank 0, position (0,0)
- We draw it at position (76, 56) which is near the center of our 160x120 screen
- The sprite is 8x8 pixels in size
- The last parameter
0
means that color 0 in the sprite will be treated as transparent
43.5 Moving Sprites: Bringing Your Game to Life
Of course, most games don’t just display static sprites - they move them around! Let’s create a simple example where we can control a sprite with the arrow keys:
import pyxel
class MovingSprite:
def __init__(self):
160, 120, title="Moving Sprite")
pyxel.init(# We're assuming there's already an 8x8 sprite at position (0,0) in image bank 0
# Initialize sprite position
self.sprite_x = 80
self.sprite_y = 60
self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
# Move sprite with arrow keys
if pyxel.btn(pyxel.KEY_LEFT):
self.sprite_x = max(self.sprite_x - 2, 0)
if pyxel.btn(pyxel.KEY_RIGHT):
self.sprite_x = min(self.sprite_x + 2, 152) # 160 - 8
if pyxel.btn(pyxel.KEY_UP):
self.sprite_y = max(self.sprite_y - 2, 0)
if pyxel.btn(pyxel.KEY_DOWN):
self.sprite_y = min(self.sprite_y + 2, 112) # 120 - 8
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw the sprite at its current position
self.sprite_x, self.sprite_y, 0, 0, 0, 8, 8, 0)
pyxel.blt(
# Display instructions
5, 5, "Use arrow keys to move", 7)
pyxel.text(5, 15, "Press Q to quit", 7)
pyxel.text(
MovingSprite()
In this example:
- We store the sprite’s position in variables
sprite_x
andsprite_y
- We update these variables based on arrow key presses
- We use
min
andmax
to keep the sprite within the screen boundaries - We draw the sprite at its current position each frame
43.6 Transparency in Sprites
You might have noticed that in our blt()
calls, we’ve been including a final parameter 0
. This is the colkey
parameter, which specifies which color in your sprite should be treated as transparent.
In Pyxel, color 0 (black) is often used as the transparent color in sprites. When a pixel in your sprite has this color, Pyxel won’t draw it, allowing the background to show through.
For example, if we have a sprite of a circle with color 0 around it, only the circle will appear when drawn, not the rectangular background:
# Draw a sprite with transparency
0, 0, 0, 8, 8, 0) # Color 0 is transparent
pyxel.blt(x, y,
# Draw the same sprite without transparency
0, 0, 0, 8, 8) # No transparent color pyxel.blt(x, y,
You can set any color (0-15) as the transparent color, or omit the parameter entirely if you don’t want any transparency.
43.7 Practice Time: Your First Sprite Quest
Now it’s your turn to create a Pyxel application using sprites. Complete these challenges:
Create a game that displays a sprite (assume it’s at position 0,0 in image bank 0)
Make the sprite move with the arrow keys
Add a second non-moving sprite somewhere else on the screen (using the same sprite image)
Here’s a starting point for your quest:
import pyxel
class MyFirstSpriteGame:
def __init__(self):
160, 120, title="My First Sprite Game")
pyxel.init(# We're assuming there's already an 8x8 sprite at position (0,0) in image bank 0
# Initialize your variables here
self.player_x = 80
self.player_y = 60
self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
# Update player position based on arrow keys
# Your code here
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw the player sprite
# Your code here
# Draw a stationary sprite
# Your code here
# Display instructions
5, 5, "Use arrow keys to move", 7)
pyxel.text(
# Create and start your game
MyFirstSpriteGame()
43.8 Common Bugs to Watch Out For
As you start working with sprites in Pyxel, watch out for these common issues:
Incorrect File Paths: If you’re loading sprites from external files, make sure the file paths are correct and the files exist in the expected location.
Transparent Color Issues: If your sprite has an unexpected background, check that you’ve specified the correct transparent color in your
blt()
call.Drawing Outside the Screen: If you position sprites outside the screen boundaries, they won’t cause errors but won’t be visible. Use boundary checks to keep sprites in view.
Coordinate Confusion: Remember that
(u, v)
coordinates refer to positions within the image bank, while(x, y)
coordinates refer to positions on the screen.Sprite Size Errors: Make sure the width and height parameters in your
blt()
call match the actual dimensions of your sprite, or you may get unexpected results.
43.9 Conclusion and Resources for Further Exploration
You’ve now learned the fundamentals of loading and displaying sprites in your Pyxel games. This is just the beginning of your journey with sprites, but these basics will serve as the foundation for more advanced sprite techniques in future lessons.
To further enhance your understanding of sprites in Pyxel, check out these resources:
Pyxel GitHub Documentation - The official documentation for Pyxel, including details on the
blt()
function and image banks.Pyxel Examples - Official examples that demonstrate sprite usage in various contexts.
Pixel Art for Beginners - If you want to create your own sprites, these beginner tutorials will help you get started.
In our next lessons, we’ll build on this foundation to explore more advanced sprite techniques like flipping, animation, and using multiple sprites together. Keep practicing with basic sprite loading and display – mastering these fundamentals is crucial for creating engaging visual experiences in your games!