CANVAS 2D · SINGLE FILE · NO LIBRARIES

BREAKOUT v1.0

Eight columns. Four rows. Thirty-two blocks of cyan. One three-pixel ball at four pixels a frame — and three lives to spend.

STATE READY
FPS 60
TICK 0
PLATE 01 — 400 × 600
400×600 · 8×4 · 50×20
◀ ▶ / MOUSE / DRAG · SPACE SERVE · P PAUSE
02

COLLISION MODEL

HOW THE BALL DECIDES

  1. 01

    SUBSTEP THE TICK

    Velocity is split into slices of 2 px or less before anything is tested, so a 3 px ball travelling 4 px a frame can never tunnel a 17 px brick. That gives two to three collision passes per 60 Hz tick.

  2. 02

    AABB OVERLAP

    The ball is boxed as a square of side 6 and tested against every live brick rect. Bricks live in an 8-column grid addressed as cell = row × 8 + col, so the scan is a flat 32-cell loop with zero allocation.

  3. 03

    MINIMUM-PENETRATION AXIS

    Overlap is measured on both axes. The shallower axis is the one that was crossed, so it gets flipped and the ball is pushed clear of the face. Top/bottom hits invert vy, side hits invert vx.

  4. 04

    ONE RESOLUTION PER SLICE

    Where several bricks overlap the box, only the shallowest resolves; the brick dies immediately and the ball is displaced out of the face, so a re-collision on the next slice is impossible and the speed magnitude is never altered.

  5. 05

    PADDLE ANGLE + ENGLISH

    rel = (ballX − paddleCentre) ÷ 30, mapped to ±62°. Edges send the ball flat and wide, dead centre sends it straight back up, and paddle travel is added as sidespin before the vector is renormalised.

PLAYFIELD400 × 600
BRICK CELL50 × 20
BALL RADIUS3 px
SPEED BAND3.00 – 4.00 px/tick
PADDLE60 × 10 · y 580 · x 0–340
SCORE10 / brick · 320 max
SIM RATEfixed 60 Hz accumulator
LIVES3