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.