AABB · single resolution per substep
| Face | Test | Response | Guard |
|---|---|---|---|
| Wall | x−r < 0 · x+r > 400 · y−r < 0 | dx = −dx / dy = |dy| | hard reposition to contact |
| Paddle | overlap & dy > 0 & prevBottom ≤ ypad | θ = offset · 60° → dx, dy | top / side / underside resolved separately |
| Brick | cell lookup 8×4, nearest penetration | flip dy (top/bottom) · flip dx (side) | one brick per substep, +10 pts |
| Void | y − r > 600 | lives −− · ball respawns on paddle | game over at zero lives |
vanilla js · zero libraries