Arcade · Vanilla Canvas Build

BreakOut

32 bricks. 3 lives. One 60 px paddle. Fixed-timestep physics, swept AABB collision, zero dependencies.

State Ready FPS 60 Grid 8×4 Max 320
Field 400×600 Tap / click the field to launch Paddle 60×10

Collision model

Every frame the ball is advanced, then tested against the wall rails, the paddle AABB and the live brick grid. Candidates are ranked by squared distance to their centre, and only the closest one is resolved — no multi-brick chain flips.

Side is inferred from the pre-move position: if the ball's previous span sat entirely above the brick's top edge it's a vertical hit (dy flips); if it sat to the left or right it's a lateral hit (dx flips). When both axes are ambiguous, the smaller penetration axis wins. The ball is then pushed clear along that normal, so it can never re-collide on the next frame.

Paddle angles

Contact maps hit offset to a ±60° exit vector: dx = sin(rel·maxA), dy = −cos(rel·maxA). Centres return steep, edges send it flat and fast. A vertical clamp keeps the ball from locking into a horizontal loop, and magnitude is renormalised after every bounce.

Perf budget

  • Loop accumulator @ 60Hz
  • Brick sprite cached offscreen
  • Buffer devicePixelRatio ≤ 2
  • Draw calls / frame ~60
  • Dependencies none