Cabinet 01 · HTML5 Canvas · No libraries

BREAKOUT

32 bricks. One 6px ball. A 60-pixel slab of white between you and the void.

RESOLUTION 400 × 600 GRID 8 × 4 · 50×20 BALL Ø6px TARGET 60 FPS

← → / mouse · drag on screen for touch · space launch · P pause · R restart

Under the glass

Four things that separate a playable brick breaker from a ball that teleports through walls.

01

AABB with normal recovery

The ball is treated as a 6px box against each brick. All four penetration depths are measured, the smallest one wins, and that axis alone flips — so a top strike reverses dy, a side strike reverses dx. The ball is also pushed flush to the face it hit, so it can never be left inside a brick.

02

One resolution per step

Each frame's movement is sliced into sub-steps of ≤1.4px. Bricks are scanned for the closest overlap and only that one is destroyed, with a short cooldown keyed to brick id — no double flips, no chain-reacting row wipes, magnitude always held at 3.44px/frame.

03

Paddle english

Contact point maps to exit angle: dead centre fires straight up, the tips throw the ball out to ±62°, with a slice of paddle velocity mixed in. A floor on the vertical component (|dy| ≥ 0.30 × speed) kills the infinite horizontal grind.

04

Fixed timestep, honest touch

Physics runs on a 16.6ms accumulator, so a 120Hz phone and a 60Hz monitor solve the same game. Touch events are preventDefault-bound to the canvas and mapped through getBoundingClientRect, so finger position converts to true canvas space at any CSS size, portrait or landscape.