DRAG THE FIELD · ARROWS · SPACE
Canvas 2D · 400×600 field · 8×4 brick grid · fixed 60 Hz step · vanilla JS
// ball-vs-brick: nearest hit only, then break for (b of bricks) { if (circleRect(ball, b)) pick nearest(b); } const ox = (R + b.w/2) - |ball.x - b.cx|; const oy = (R + b.h/2) - |ball.y - b.cy|; if (ox < oy) { dx = sign(ball.x-b.cx) * |dx|; ball.x += sign*(ox+.6); } else { dy = sign(ball.y-b.cy) * |dy|; ball.y += sign*(oy+.6); } break; // no double flips, no tunnelling clamp(|dy| >= 1.1) // the ball never runs flat renormalize(|v| = speed) // magnitude always preserved // paddle: angle from contact point, -60° … +60° rel = (ball.x - padCenter) / (30); v = speed * [ sin(rel*60°), -cos(rel*60°) ] + 0.06 * padMomentum