canvas arcade · unit 01 · vanilla js

BREAKOUT

8×4 GRID · 50×203 LIVESMAX 32060 FPS TARGET
←→ move space launch s focus · slows ball p pause drag touch paddle

How it works

Every brick is a cell in an 8×4 grid: x = col × 50, y = top + row × 20. Collisions are explicit AABB expanded by the ball radius, then resolved on the axis of least penetration — so a top hit flips dy, a side hit flips dx, and only the deepest brick per sub-step is processed.

Paddle bounces use a normalized hit offset: the ball leaves the centre vertically and leaves the edge at roughly 58°, so aiming is yours, not the RNG's.

Playfield
400×600 canvas, 3px walls, 52px HUD band, bricks live 60px down
Ball
r=3, normalized (2, −2.8) launch, 3.4 → 4.3 px/frame, magnitude restored after every bounce
Paddle
60×10 at y=580, clamped 0–340, side faces bounce the ball back into play
Sub-stepping
Motion split into 4 micro-steps per frame at 60Hz fixed timestep — no tunnelling, no frame-rate drift on 120Hz phones
Anti-stick
Ball is pushed clear of the brick it just broke; a cleared brick can never re-collide; vertical lock is guarded by a minimum |dy|
Mobile
touchstart / touchmove / touchend with grab-offset dragging, works portrait & landscape from 320px
Clear bonus
+25 per surviving life, added only on a win — brick score stays capped at 320