BREAK/OUT v1.0
CANVAS 400×600 60 FPS INPUT: LIVE
CATHODE 400×600 · 8×4 GRID INSERT COIN ▸ FREE
CABINET 01 · 32 BRICKS · 320 POINTS · 3 LIVES

BREAK/OUT

One paddle. Thirty-two cyan bricks. A 3-pixel ball that never stops moving — resolved by pure AABB math at 60fps.

400×600CANVAS
8×4BRICK GRID
320MAX CLEARED

Bounce angle is derived from where the ball strikes the paddle — edges fling it wide, the centre sends it straight back. One brick is destroyed per simulation step, the ball is ejected out of the brick, and its velocity magnitude is renormalised so it can never stall, tunnel, or lock horizontal.

SINGLE HTML FILENO LIBRARIES requestAnimationFrameFIXED TIMESTEP TOUCH + KEYBOARD + MOUSEWEB AUDIO SFX
LIVE TELEMETRY // READOUT
SCORE0
BEST0
LIVES
WAVE1
GRID
COMBO
BALL ·DX+0.00
BALL ·DY-0.00
SPEED3.40
UPTIME00:00
FRAME60.0
EVENTS
HOW TO PLAY // INPUT MAP

THREE WAYS
TO STEER

←→ AD SPACEP R

Desktop — move the mouse across the screen, or hold ← → / A D. Space launches, P pauses, R restarts.

Mobile — drag anywhere on the display; the paddle tracks your finger with smoothing. Tap the centre of the screen to launch, pause, or press an on-screen button. Portrait and landscape both scale cleanly down to 320px wide.

ENGINE // COLLISION RESOLUTION

THE BALL NEVER
LIES TO YOU

01 / AABB

NEAREST-POINT TEST

Every brick is a 50×20 box. The ball's centre is clamped into the box to find the closest point; if that gap is under r=3, contact is real. Every alive brick is tested, the shallowest penetration wins, and exactly one collision resolves per step — no multi-brick chains, no tunnelling.

02 / AXIS

SIDE DETECTION

Overlaps are computed on both axes: ox = 25+3 − |Δx|, oy = 10+3 − |Δy|. The smaller overlap is the collision normal — so a top drop flips dy, a glancing entry flips dx, and the ball is repositioned flush to the brick face so it can never re-collide next frame.

03 / LOCK

ANTI-STALL GUARD

After any side flip, if the vertical component drops below 0.30·|v| it is re-seeded and the vector renormalised. The magnitude is preserved forever — 3.4 px/frame at wave 1. A perfectly horizontal loop is mathematically impossible.

04 / PADDLE

ANGLE BY CONTACT

Contact offset is mapped to ±60°: θ = rel · 60°, then dx = |v|·sin θ, dy = −|v|·cos θ. Centre hits return straight up; the outer 3px rim kicks a steep diagonal. Paddle velocity adds a little english, capped by renormalisation.

05 / RHYTHM

FIXED TIMESTEP

The loop runs requestAnimationFrame with a 16.67 ms accumulator and a 4-step clamp, so a phone throttled to 30Hz and a 144Hz monitor simulate identically. Sub-stepping moves the ball in slices, so fast diagonals cannot skip a brick row.

06 / FIELD

EDGE CASES

Paddle is hard-clamped to x ∈ [0,340]. Corners: a simultaneous wall + brick hit resolves the wall first, then the brick. A ball clipping the top wall at y<3 reflects without eating a score. Life loss resets the ball to the paddle centre and demands a fresh launch.

SPECIFICATION // VERBATIM

EVERY NUMBER
IN THE BUILD

CANVAS400 × 600 px logical, DPR-scaled backing store2/3 ratio, fluid CSS
BRICK GRID8 cols × 4 rows · 50×20 · pos = row*20, col*5032 bricks · 320 pts
BALLr = 3 px · start (200, 570) · |v| = 3.40 px/frame+0.25 per wave
LAUNCH VECTOR(2, −2.8) normalised × speeddx +1.56 / dy −2.18
PADDLE60 × 10 px · y = 580 · travel 0 → 340±60° deflection
SCORING+10 per brick · combo & speed feed a clear bonuscleared cap 320
LIVES3 · lost when the ball exits below the paddle linegame over at 0
RENDERPre-baked background, vignette & scanline layers≤200 particles
INPUTtouchstart / touchmove / touchend + pointer + keyspreventDefault on canvas