Back to Neon Breakout

Documentation

README

Neon Breakout

A browser-based brick breaker game built with HTML5 Canvas. Single file, no dependencies, works offline.

How to Play

  • Open src/index.html in any modern browser (double-click the file).
  • Press Space or Click to start.
  • Press Space or Click to launch the ball.
  • Move the paddle to bounce the ball and destroy all bricks.
  • Clear all 32 bricks to win. Lose all 3 lives and it is game over.
  • Controls

    InputAction
    Left Arrow / AMove paddle left
    Right Arrow / DMove paddle right
    MousePaddle follows cursor horizontally
    Space / ClickStart game, launch ball, play again
    Keyboard and mouse work simultaneously. Mouse position overrides keyboard when the cursor is on the canvas.

    Game Rules

    • 3 lives per game.
    • 32 bricks arranged in 4 rows of 8.
    • Point values by row (top to bottom): 40, 30, 20, 10.
    • Maximum score: 800 points.
    • Ball speed increases by 2% per brick destroyed, capped at 700 px/s.
    • Ball speed is not reset when a life is lost.
    • High score is saved to localStorage and persists across sessions.

    Brick Colors

    RowColorPoints
    TopMagenta40
    2ndLime30
    3rdOrange20
    BottomPurple10

    File Structure

    shell
    3-development/
      src/
        index.html        # Complete playable game (single file)
        game-logic.js     # Exported pure functions for testing
      tests/
        game-logic.test.js  # Unit tests (node:test + node:assert/strict)
      docs/
        README.md         # This file
      package.json        # ES module configuration for test runner

    Why Two Copies of the Logic?

    index.html is a self-contained single file with all JS inline. It cannot use import/export. To enable unit testing with Node.js, the same pure game logic functions are exported from game-logic.js. The two files must be kept in sync.

    Running Tests

    bash
    cd projects/003-canvas-game/3-development
    node --test tests/game-logic.test.js

    Expected output: 105 tests passing across 21 suites covering:

    • Constants validation
    • Wall collisions (top, left, right, corners)
    • Paddle collision detection and reflection angles
    • Brick collision detection, destruction, and scoring
    • Floor collision (life loss)
    • Win condition checking
    • Brick grid initialization and positioning
    • Reflection angle calculation (30-150 degree range)
    • Ball position updates with delta-time
    • Paddle position updates (keyboard, mouse, clamping)
    • State machine transitions (TITLE, SERVING, PLAYING, GAME_OVER, WIN)
    • Game reset and ball-to-paddle reset
    • Integration tests (speed curves, full game cycles, score accumulation)
    • Edge cases (simultaneous keys, wall-edge paddles, last brick + last life)

    Sound

    Sound uses the Web Audio API with programmatic sine wave generation:

    • Paddle hit: 220 Hz, 50ms
    • Brick break: 440 Hz, 50ms
    • Life lost: 110 Hz, 200ms
    Sound can be disabled by setting SOUND_ENABLED = false in the source code. If the browser blocks AudioContext, sound is automatically disabled with no error shown.

    Browser Compatibility

    Tested in Chrome 90+, Firefox 90+, Safari 15+, and Edge 90+. Works via file:// protocol with no server required.

    © 2026 Jonathan Leahy · v1.0.1