Game Dev 101
Progress
0/22

Lesson 11 of 22, in world 4: Visuals & Worlds

Sprites & Animation

Time
About 15 min
Builds on
Coordinates & TransformsHandling InputGravity, Jumping & Collision Response

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.

JavaScript
// 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 screen
LiveSprite sheet → flipbook animation

Walk 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

JavaScript
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

  1. Find the best-looking run speed with the slider. Then think: should the animation speed depend on how fast the character moves?
  2. Design a 2-frame "hurt" animation on graph paper using the same 12×12 grid.
  3. Download a free Kenney character pack and find its sprite sheet. How big is each frame?