Game Dev 101
Progress
0/22

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

Cameras & Scrolling

Time
About 15 min
Builds on
Coordinates & TransformsVelocity, Acceleration & FrictionDelta Time & Fixed Timesteps

Once your level is bigger than the screen, you need a camera: a movable window onto the world. In 2D, a camera is shockingly simple — it’s just an offset subtracted from everything you draw.

World space vs. screen space

Objects live in world space (the player is at x = 1800 in a 2400-wide level). The screen only shows 640 pixels. The camera has a position too, and screen = world − camera. Moving the camera right makes everything on screen slide left.

JavaScript
function render() {
  ctx.save()
  ctx.translate(-camera.x, -camera.y)  // apply the camera (lesson 4: transforms!)
  drawLevel(); drawPlayer(); drawEnemies()  // all in world coordinates
  ctx.restore()
  drawHUD()                             // score, health: screen coordinates, not affected
}
LiveFollow camera

Fly around a world that is 2400×1200 px — much larger than the 640×360 screen — with arrow keys / WASD. The minimap shows the whole world and the camera's view rectangle. Try smoothing 0 (rigid), the dead zone, and parallax.

Smooth following with lerp

A camera glued to the player feels stiff. Instead, move it a fraction of the remaining distance each frame — linear interpolation (lerp). It moves fast when far away and eases in as it arrives.

JavaScript
const target = { x: player.x - SCREEN_W / 2, y: player.y - SCREEN_H / 2 }
const t = 1 - Math.exp(-SMOOTHING * dt)   // frame-rate independent (lesson 3)
camera.x += (target.x - camera.x) * t
camera.y += (target.y - camera.y) * t

More camera techniques

  • Dead zone — the camera only moves when the player leaves a box in the middle. Small movements don’t shake the view.
  • Clamping — stop at the level edges so the player never sees the void outside.
  • Look-ahead — offset the camera in the direction of movement so the player sees what’s coming.
  • Parallax — background layers scroll slower (multiply camera by 0.1–0.5), creating a sense of depth.
  • Screen shake — briefly add a random offset (lesson 19).

Key takeaways

  • screen = world − camera. A 2D camera is a translate before drawing the world.
  • Draw HUD after restoring the transform so it stays in screen space.
  • Smooth follow with frame-rate-independent lerp; add dead zones, clamping, parallax.

Check yourself

Q1. Camera at (500, 200). An enemy at world (620, 260) is drawn on screen at…

Q2. You click at screen (100, 100) with camera at (800, 0). Which world point did you click?

Q3. Why do far-away background layers scroll slower?

Exercises

  1. Turn clamping off and fly to a corner. What do you see? Why do most games clamp?
  2. Implement look-ahead: target = player + velocity × 0.3. Try it in your head with the dead zone — do they conflict?
  3. Add zoom: scale(z, z) around the screen centre. Where in the transform order does it go?