Example Assets Needed:
To follow along with this chapter's examples, you'll need these image files:
- player.png — 32x32 character sprite (or 128x32 spritesheet with 4 frames)
- hero.png — 32x32 character spritesheet (4+ frames for animation)
- coin.png — 16x16 collectible sprite
- enemy.png — 32x32 enemy sprite
- background.png — A simple background image
- icon.png, powerup.png, ghost.png, arrow.png, title.png — Various UI/game sprites
You can draw these yourself (see Chapter 5!), use free assets from sites like OpenGameArt.org or itch.io, or use simple colored rectangles as placeholders.
Circles and lines are great for learning, but let's be honest—you want your games to look GOOD. You want sprites! Characters! Backgrounds! Explosions that look like actual explosions instead of expanding circles!
Good news: Crash BASIC makes it super easy to use real images in your games. And once you see how simple it is, you'll never want to go back to drawing everything with primitives.
Let's turn your games into works of art!
The Resources Widget: Your Art Gallery
Before we can use images in our code, we need to get them INTO Crash BASIC. That's what the Resources widget is for.
Look at the Crash BASIC IDE. See that panel with the folder icon? That's the Resources widget. It's where all your game's assets live—images, sounds, everything.
To add an image:
- Click the Resources tab in the IDE
- Click the Upload button (or drag and drop files directly!)
- Select your image file (PNG, JPG, or GIF)
- Done! The image is now part of your project
Pro tip: PNG files are best for game sprites because they support transparency. That means the background of your sprite can be see-through, so your character doesn't have an ugly rectangle around them!
Loading Images: LOADPNG
Once your image is in the Resources widget, you need to tell your program to load it. That's what LOADPNG does:
SCREEN 13
LOADPNG "player.png", "player"Let's break that down:
"player.png"— The filename (exactly as it appears in Resources)"player"— The name you'll use to refer to this image in your code
The second name can be anything you want! You could load "my_super_cool_character_sprite_v3_final_FINAL.png" and call it just "hero". Much easier to type!
You can also use LOADIMG—it does exactly the same thing:
LOADIMG "enemy.png", "badguy"Displaying Images: PUTIMAGE
Now for the fun part—putting images on screen!
SCREEN 13
LOADPNG "player.png", "player"
PUTIMAGE (100, 50), "player"
PAUSEThat's it! The image appears at coordinates (100, 50). The position is where the top-left corner of the image goes.
Let's make it move:
SCREEN 13
LOADPNG "player.png", "player"
x = 0
DO
BEGIN FRAME
CLS
PUTIMAGE (x, 100), "player"
END FRAME
x = x + 2
IF x > 320 THEN x = 0
DELAY 16
LOOPYour character glides across the screen! Same animation principle as before—erase, draw, repeat—but now with REAL art instead of circles.
Transparency: The Magic of PNG
Here's why PNG files are magical: they can have transparent pixels.
Imagine you have a character sprite. The character is drawn on a canvas, but the area around them? That's transparent. When you PUTIMAGE, only the character shows up—not an ugly colored rectangle.
This just works automatically with PNG files that have transparency. No special code needed!
If you're making your own sprites, use any image editor (like GIMP, Photoshop, or even free online tools) and save as PNG with transparency enabled. The transparent pixels will stay transparent in Crash BASIC.
Sprite Sheets: Animation Made Easy
Real games don't use separate files for every animation frame—that would be hundreds of files! Instead, they use sprite sheets: one image with all the frames arranged in a grid.
+-------+-------+-------+-------+
| Frame | Frame | Frame | Frame |
| 0 | 1 | 2 | 3 |
+-------+-------+-------+-------+
| Frame | Frame | Frame | Frame |
| 4 | 5 | 6 | 7 |
+-------+-------+-------+-------+To load a sprite sheet, tell Crash BASIC the size of each frame:
SCREEN 13
LOADPNG "hero.png", "hero" AS SPRITESHEET(32, 32)This tells Crash BASIC: "This image contains frames that are each 32x32 pixels." It automatically figures out how many frames there are based on the image size.
Frame numbering: Frames start at 0 in the top-left, go left-to-right, then wrap to the next row. So in a 4x2 grid, frames are numbered 0-3 on top, 4-7 on bottom.
Now you can show specific frames:
SCREEN 13
LOADPNG "hero.png", "hero" AS SPRITESHEET(32, 32)
PUTIMAGE (100, 100), "hero", 0 ' Frame 0
PUTIMAGE (150, 100), "hero", 1 ' Frame 1
PUTIMAGE (200, 100), "hero", 2 ' Frame 2
PAUSEAnimation: Bringing Sprites to Life
Let's animate! We'll cycle through frames to create movement:
SCREEN 13
LOADPNG "hero.png", "hero" AS SPRITESHEET(32, 32)
frame = 0
x = 100
DO
BEGIN FRAME
CLS
PUTIMAGE (x, 100), "hero", frame
END FRAME
' Advance to next frame
frame = frame + 1
IF frame >= FRAMECOUNT("hero") THEN frame = 0
DELAY 100 ' Slower delay so animation is visible
LOOPFRAMECOUNT("hero") returns how many frames the sprite sheet has. This way, your code works no matter how many frames the artist adds later!
Let's combine movement with animation:
SCREEN 13
LOADPNG "hero.png", "hero" AS SPRITESHEET(32, 32)
frame = 0
x = 0
frameTimer = 0
DO
BEGIN FRAME
CLS
' Draw the hero
PUTIMAGE (x, 100), "hero", frame
END FRAME
' Move
x = x + 2
IF x > 320 THEN x = -32
' Animate (change frame every 5 game loops)
frameTimer = frameTimer + 1
IF frameTimer >= 5 THEN
frameTimer = 0
frame = frame + 1
IF frame >= FRAMECOUNT("hero") THEN frame = 0
END IF
DELAY 16
LOOPNow your character walks across the screen with proper animation!
Scaling: Bigger and Smaller
Want to make an image bigger or smaller? Use the SCALE modifier:
SCREEN 13
LOADPNG "icon.png", "icon"
' Original size
PUTIMAGE (10, 50), "icon"
' Scaled to 64x64 pixels
PUTIMAGE (100, 50), "icon", SCALE(64, 64)
' Scaled to 128x128 pixels
PUTIMAGE (200, 50), "icon", SCALE(128, 128)
PAUSESCALE takes the target width and height in pixels. The image stretches or shrinks to fit.
This is great for:
- Making items grow when collected
- Zoom effects
- Using the same sprite at different sizes
SCREEN 13
LOADPNG "powerup.png", "star"
size = 16
growing = 1
DO
BEGIN FRAME
CLS
PUTIMAGE (144, 84), "star", SCALE(size, size)
END FRAME
IF growing THEN
size = size + 1
IF size >= 64 THEN growing = 0
ELSE
size = size - 1
IF size <= 16 THEN growing = 1
END IF
DELAY 16
LOOPA pulsing power-up effect!
Transparency Effects: ALPHA
Want a ghost that's see-through? A fading explosion? Use ALPHA:
SCREEN 13
LOADPNG "ghost.png", "ghost"
' Fully opaque (solid)
PUTIMAGE (50, 100), "ghost", ALPHA(1.0)
' 50% transparent
PUTIMAGE (150, 100), "ghost", ALPHA(0.5)
' Almost invisible
PUTIMAGE (250, 100), "ghost", ALPHA(0.2)
PAUSEALPHA goes from 0.0 (completely invisible) to 1.0 (completely solid).
Let's make a fade-in effect:
SCREEN 13
LOADPNG "title.png", "title"
' Fade in
FOR alpha = 0 TO 10
BEGIN FRAME
CLS
PUTIMAGE (80, 80), "title", ALPHA(alpha / 10)
END FRAME
DELAY 100
NEXT alpha
PAUSEFlipping: Mirror Images
Need your character to face left AND right, but only have sprites facing one direction? Use FLIPX and FLIPY:
SCREEN 13
LOADPNG "hero.png", "hero" AS SPRITESHEET(32, 32)
' Normal (facing right)
PUTIMAGE (50, 100), "hero", 0
' Flipped horizontally (facing left)
PUTIMAGE (150, 100), "hero", 0, FLIPX
' Flipped vertically (upside down)
PUTIMAGE (250, 100), "hero", 0, FLIPY
PAUSEHere's a character that faces the direction they're moving:
SCREEN 13
LOADPNG "hero.png", "hero" AS SPRITESHEET(32, 32)
x = 160
facingRight = 1
DO
k$ = INKEY$
IF k$ = "a" THEN
x = x - 3
facingRight = 0
ELSEIF k$ = "d" THEN
x = x + 3
facingRight = 1
END IF
BEGIN FRAME
CLS
IF facingRight THEN
PUTIMAGE (x, 100), "hero", 0
ELSE
PUTIMAGE (x, 100), "hero", 0, FLIPX
END IF
END FRAME
DELAY 16
LOOPOne sprite, two directions!
Rotation: Spinning Things Around
Want to rotate an image? Use ROTATE:
SCREEN 13
LOADPNG "arrow.png", "arrow"
angle = 0
DO
BEGIN FRAME
CLS
PUTIMAGE (144, 84), "arrow", ROTATE(angle)
END FRAME
angle = angle + 3
IF angle >= 360 THEN angle = 0
DELAY 16
LOOPBy default, ROTATE spins the image around its top-left corner. But usually you want to rotate around the CENTER. Use the optional origin parameters:
' ROTATE(angle, originX, originY)
' originX and originY are 0-1, where 0.5 = center
PUTIMAGE (144, 84), "arrow", ROTATE(angle, 0.5, 0.5)(0, 0)= top-left corner(0.5, 0.5)= center (most common!)(1, 1)= bottom-right corner(0.5, 1)= bottom-center (good for characters pivoting on their feet)
Here's a spinning power-up that rotates around its center:
SCREEN 13
LOADPNG "coin.png", "coin"
angle = 0
DO
BEGIN FRAME
CLS
PUTIMAGE (144, 84), "coin", ROTATE(angle, 0.5, 0.5)
END FRAME
angle = (angle + 5) MOD 360
DELAY 16
LOOPCombining Modifiers
The best part? You can combine all these modifiers together!
SCREEN 13
LOADPNG "ghost.png", "ghost"
angle = 0
alpha = 0.7
DO
BEGIN FRAME
CLS
' A semi-transparent, scaled, rotating ghost facing left
PUTIMAGE (144, 84), "ghost", ALPHA(alpha), SCALE(64, 64), ROTATE(angle, 0.5, 0.5), FLIPX
END FRAME
angle = (angle + 2) MOD 360
DELAY 16
LOOPModifiers can be in any order. Go wild!
Putting It All Together: A Sprite-Based Game
Let's make a simple game using everything we learned:
SCREEN 13
' Load our sprites
LOADPNG "player.png", "player" AS SPRITESHEET(32, 32)
LOADPNG "coin.png", "coin"
LOADPNG "background.png", "bg"
' Game state
playerX = 144
playerY = 150
playerFrame = 0
facingRight = 1
frameTimer = 0
coinX = INT(RND * 280) + 20
coinY = INT(RND * 150) + 20
coinAngle = 0
score = 0
DO
k$ = INKEY$
' Player movement
moving = 0
IF k$ = "a" AND playerX > 0 THEN
playerX = playerX - 3
facingRight = 0
moving = 1
ELSEIF k$ = "d" AND playerX < 288 THEN
playerX = playerX + 3
facingRight = 1
moving = 1
END IF
' Animate player when moving
IF moving THEN
frameTimer = frameTimer + 1
IF frameTimer >= 5 THEN
frameTimer = 0
playerFrame = playerFrame + 1
IF playerFrame >= FRAMECOUNT("player") THEN playerFrame = 0
END IF
ELSE
playerFrame = 0
END IF
' Spin the coin
coinAngle = (coinAngle + 5) MOD 360
' Check coin collection
dx = (playerX + 16) - (coinX + 8)
dy = (playerY + 16) - (coinY + 8)
dist = SQR(dx * dx + dy * dy)
IF dist < 20 THEN
score = score + 10
coinX = INT(RND * 280) + 20
coinY = INT(RND * 150) + 20
END IF
' Draw everything
BEGIN FRAME
CLS
PUTIMAGE (0, 0), "bg"
PUTIMAGE (coinX, coinY), "coin", ROTATE(coinAngle, 0.5, 0.5)
IF facingRight THEN
PUTIMAGE (playerX, playerY), "player", playerFrame
ELSE
PUTIMAGE (playerX, playerY), "player", playerFrame, FLIPX
END IF
LOCATE 1, 1
PRINT "Score: "; score
END FRAME
DELAY 16
LOOPThis game has:
- A background image
- An animated player that faces the direction they're moving
- A spinning coin to collect
- Score tracking
All with REAL art instead of circles!
Quick Reference
| Command | What It Does |
|---|---|
LOADPNG "file", "name" |
Load an image |
LOADPNG "file", "name" AS SPRITESHEET(w, h) |
Load as sprite sheet |
PUTIMAGE (x, y), "name" |
Display image |
PUTIMAGE (x, y), "name", frame |
Display specific frame |
ALPHA(0.0-1.0) |
Set transparency |
SCALE(width, height) |
Resize image |
FLIPX |
Mirror horizontally |
FLIPY |
Mirror vertically |
ROTATE(angle) |
Rotate (from top-left) |
ROTATE(angle, 0.5, 0.5) |
Rotate around center |
FRAMECOUNT("name") |
Get number of frames |
But What If I'm Not an Artist?
Here's a secret: neither am I! And neither are a LOT of game developers. But that doesn't have to stop you.
First: Try anyway. Seriously! Open up any image editor—even MS Paint—and just START drawing. Your first sprites will probably look terrible. That's okay! Everyone's first sprites look terrible. The important thing is that YOUR game has YOUR art, and there's something special about that.
Start simple:
- Stick figures are valid game characters
- Colored squares can be enemies
- A yellow circle with two dots is a face
- Simple shapes with bold outlines read well at small sizes
Second: Let AI help you level up.
We live in an amazing time. AI art tools can take your rough sketches and transform them into something polished. Here's the workflow I recommend:
- Draw your best attempt — Even if it's messy, get your idea down
- Use AI to enhance it — Tools like:
- Midjourney or DALL-E — Describe what you want, get variations
- Stable Diffusion — Free and runs locally
- Pixelicious or Pixel It — Convert any image to pixel art
- Aseprite — Not AI, but amazing for pixel art (has great tutorials!)
- Edit the results — AI gives you a starting point, then you tweak it
You can also describe your game to AI: "16x16 pixel art sprite sheet of a knight character, 4 walking frames, transparent background, retro game style" — and get something usable!
The key insight: AI is a tool, not a replacement. Use it to bridge the gap between what you can imagine and what you can draw. As you practice, you'll need it less and less. But there's no shame in using every tool available to bring your vision to life.
Your game with "AI-assisted art that you directed" is infinitely better than "a game you never made because you couldn't draw."
Tips for Great Game Art
- Use PNG for sprites — Transparency is your friend!
- Keep sprite sheets organized — Same-size frames, consistent spacing
- Start small — 16x16 or 32x32 pixels is plenty for retro games
- Free resources exist! — Sites like OpenGameArt.org have tons of free sprites
- SCALE lets you cheat — One small sprite can be multiple sizes
- AI is your friend — Use it to enhance your rough sketches into polished art
Try It Yourself!
- Find or create a simple sprite sheet and make it walk across the screen
- Make an object that fades in, spins, then fades out
- Create a "face the mouse" effect using ROTATE (hint: ATN from Chapter 4!)
- Build a scene with a background and multiple characters
Your games are about to look SO much better!
See you in Chapter 7!
Next Chapter: We'll learn how to talk to our players—keyboard, mouse, touch, and more!