Lesson 11 of 22, in world 4: Visuals & Worlds
Sprites & Animation
So far everything has been rectangles and circles — on purpose: gameplay first, art later. Now let’s give our hero a face. In 2D games, images are called sprites, and animation is the oldest trick in the book: a flipbook of slightly different pictures shown in quick succession.
Sprites and sprite sheets
A sprite is a 2D image drawn at an object’s position. Instead of loading hundreds of separate files, artists pack every frame into one big image: a sprite sheet (or texture atlas). The game draws just one rectangular slice of it at a time. One file means one load and fast GPU rendering.
// drawImage(image, sourceX, sourceY, sourceW, sourceH, destX, destY, destW, destH)
const FRAME_W = 12, FRAME_H = 12
ctx.drawImage(sheet, frame * FRAME_W, 0, FRAME_W, FRAME_H, // which slice of the sheet
x, y, FRAME_W * 4, FRAME_H * 4) // where (and how big) on screenWalk with ←→, jump with Space. Top: the whole sprite sheet, with the frame being shown right now highlighted. The game picks an animation (idle / run / jump) from the character's state, then steps through its frames on a timer. Facing left is the same frames drawn with scale(-1, 1).
Animation = frames + timing + state
const ANIMS = { idle: [0, 0, 0, 1], run: [2, 3, 4, 5], jump: [6] }
function update(dt) {
const next = !onGround ? 'jump' : moving ? 'run' : 'idle'
if (next !== anim) { anim = next; animTime = 0 } // restart the clip on change
animTime += dt
}
function draw() {
const frames = ANIMS[anim]
const frame = frames[Math.floor(animTime * FPS) % frames.length]
drawFrame(frame)
}Notice the animation is chosen from game state, it doesn’t drive it. That keeps gameplay logic clean: physics decides that you’re airborne; the animation system just shows it. When the logic gets more complex (attack, hurt, dash…), you’ll want a state machine — lesson 15.
Where art comes from
- Free asset packs: Kenney.nl (public domain), itch.io, OpenGameArt.
- Make your own pixel art in Aseprite, LibreSprite or Piskel (free, in the browser).
- Placeholder art is fine! Many shipped games started as coloured boxes for months.
Key takeaways
- A sprite sheet packs all frames into one image; draw a sub-rectangle per frame.
- frame = floor(animTime × fps) mod frameCount.
- Pick the animation from game state; reset the clock when it changes.
- Scale pixel art by integers with smoothing off.
Check yourself
Q1. A run animation has 6 frames at 12 fps. How long is one loop?
Q2. How do you make a right-facing sprite face left cheaply?
Q3. Your pixel art looks blurry. The likely fix is…
Exercises
- Find the best-looking run speed with the slider. Then think: should the animation speed depend on how fast the character moves?
- Design a 2-frame "hurt" animation on graph paper using the same 12×12 grid.
- Download a free Kenney character pack and find its sprite sheet. How big is each frame?