Leave without saving?

Your editor changes will be lost.

Breakout-0 displays a title screen. Press w or s to switch the highlight between START and HIGH SCORES. These options are visual only in this update; neither one starts the game or opens a high-score screen yet.

State Machines

A state machine organizes a game into distinct modes, or states. For example, a complete game might have separate title, play, pause, and game-over states. Only one state is active at a time, so the game always has a clear answer to what should handle input and what should be drawn.

Game runs once per animation frame and asks StateMachine to update and render its current state. When the game needs to move to a different mode, StateMachine.change() calls exit() on the current state, selects the requested state, then calls its enter() method. The new state handles all later updates and rendering.

sequenceDiagram
    participant Main
    participant Game
    participant Machine as StateMachine
    participant Current as Current state
    participant Next as Next state

    Main->>Machine: Add title screen state
    Machine->>Current: Store state
    Note right of Machine: The title screen is current
    Main->>Game: Start game loop

    loop Each animation frame
        Game->>Machine: Update
        Machine->>Current: Update with delta time
        Game->>Machine: Render
        Machine->>Current: Render with context
    end

    Current->>Machine: Request state change
    Machine->>Current: Exit
    Machine->>Next: Enter with parameters
    Note right of Machine: The next state is current

This update contains only TitleScreenState, so it does not transition to another state yet. Later updates add the other game states and their transitions. The complete game will use this state flow:

stateDiagram-v2
    [*] --> TitleScreenState

    TitleScreenState --> PaddleSelectState: Select Start
    TitleScreenState --> HighScoreState: Select High Scores
    HighScoreState --> TitleScreenState: Press Escape

    PaddleSelectState --> ServeState: Press Enter
    ServeState --> PlayState: Press Enter
    PlayState --> ServeState: Lose a life
    PlayState --> VictoryState: Clear all bricks
    VictoryState --> ServeState: Press Enter

    PlayState --> GameOverState: Lose all lives
    GameOverState --> EnterHighScoreState: Score qualifies
    GameOverState --> TitleScreenState: Score does not qualify
    EnterHighScoreState --> HighScoreState: Confirm name

Important Code

  • main.js prepares and appends the canvas, records keydown and keyup events in keys, loads the Joystix font, registers TitleScreenState, creates Game, and starts it. It focuses the canvas and calls updateSize() after startup.
  • globals.js exports the shared canvas, drawing context, game dimensions, input map, assets, state machine, and updateSize() function. updateSize() scales the canvas to fit the browser window while preserving the game’s aspect ratio and disables image smoothing for crisp pixel art.
  • Game.js runs the game loop with requestAnimationFrame(). Each frame calculates elapsed time in seconds, updates the current state, clears the canvas, renders the current state, and schedules the next frame.
  • StateMachine.js stores states by name and forwards update() and render() calls to the current state. Adding a state also makes it current; change() exits the current state, selects the named state, and calls its enter() method.
  • states/State.js is the base class for game states. It supplies empty enter(), exit(), update(), and render() methods so subclasses can implement only the methods they need.
  • states/TitleScreenState.js is the only registered state. Its update() method toggles the highlighted menu item when w or s is pressed, clears those key values, and plays the paddle-hit sound. Its render() method draws the background and title/menu text.
  • Graphic.js wraps an Image with its source and dimensions. Its render() method draws that image using the shared drawing context.
  • SoundPool.js creates several Audio elements for one sound and cycles through them when play() is called. This lets successive sound effects use different audio elements instead of relying on one element that may still be playing.
  • globals.js creates the images.background Graphic and the sounds.paddleHit SoundPool, so states can use named shared assets without recreating them.

Read through each file carefully to understand how the title screen, input, shared resources, state management, and game loop fit together.

Powered by WebContainers
Files
Preparing Environment