Game
Game creates the services shared by every state and runs the browser animation loop. It owns the canvas dependencies, assets, input, animation helpers, and state machine so states can receive one consistent services object.
Quick Start
Section titled “Quick Start”Create the game with a Canvas and the asset definitions it should load. Register and select a state before starting the loop.
const game = new Game( canvas, fontDefinitions, imageDefinitions, soundDefinitions);
game.addState('home', HomeState);game.services.stateMachine.change('home');game.start();Services
Section titled “Services”The constructor creates these objects once and exposes them through game.services. States receive the same object through their State constructor.
flowchart TD Game --> Services["GameServices"] Services --> Drawing["canvas and context"] Services --> Input["input"] Services --> Effects["particles and timer"] Services --> Assets["fonts, images, and sounds"] Services --> Navigation["stateMachine"] Services --> State["State constructor"]
| Role | Services | Purpose |
|---|---|---|
| Drawing | canvas, context |
The canvas wrapper and its CanvasRenderingContext2D. |
| Input | input |
Keyboard and pointer input. |
| Effects | particles, timer |
Particle updates and scheduled work or tweens. |
| Assets | fonts, images, sounds |
Loaded font, image, and sound resources. |
| Navigation | stateMachine |
Registration, selection, update, and rendering of states. |
Public API
Section titled “Public API”new Game(canvas, fontDefinitions, imageDefinitions, soundDefinitions, options)
Section titled “new Game(canvas, fontDefinitions, imageDefinitions, soundDefinitions, options)”new Game(canvas, fontDefinitions, imageDefinitions, soundDefinitions, options);Creates the shared services and loads the supplied assets.
| Parameter | Type | Description |
|---|---|---|
canvas |
Canvas |
Canvas wrapper that supplies the element, drawing context, width, and height. |
fontDefinitions |
readonly FontDefinition[] |
Font assets to load. |
imageDefinitions |
readonly ImageDefinition[] |
Image assets to load. |
soundDefinitions |
readonly SoundDefinition[] |
Sound assets to load. |
options |
GameOptions (optional) |
Optional advanced configuration. Most code can omit it. |
Asset-definition arrays are read-only inputs: Game loads them into its asset services; it does not mutate the arrays.
addState(name, StateType)
Section titled “addState(name, StateType)”game.addState('settings', SettingsState);Constructs and registers a state under name. Pass the state class, not an instance. Game supplies its shared services object to the state constructor.
class SettingsState extends State { render(context) { context.fillText('Settings', 24, 24); }}
game.addState('settings', SettingsState);game.services.stateMachine.change('settings');State names are strings used later with stateMachine.change(name, props). Use stable, descriptive names such as "home", "settings", or "dialog".
start()
Section titled “start()”game.start();Starts the browser animation loop. It immediately runs the first frame and schedules later frames with requestAnimationFrame().
update(dt)
Section titled “update(dt)”game.update(dt);Advances the application by dt seconds. In normal use, gameLoop() calls this for every animation frame.
The update order is:
stateMachine.update(dt)lets the active state make decisions.particles.update(dt)advances particle effects.timer.update(dt)advances scheduled actions and tweens.
render(context)
Section titled “render(context)”game.render(context);Clears the canvas and then draws the active state followed by particles. In normal use, gameLoop() calls this after update().
Frame Pipeline
Section titled “Frame Pipeline”flowchart A["requestAnimationFrame timestamp in milliseconds"] --> B["Convert elapsed time to dt seconds"] B --> C["Game.update(dt)"] C --> D["StateMachine.update(dt)"] D --> E["ParticleSystem.update(dt)"] E --> F["Timer.update(dt)"] F --> G["Game.render(context)"] G --> H["Clear canvas"] H --> I["StateMachine.render(context)"] I --> J["ParticleSystem.render(context)"] J --> A
Understanding addState() types
Section titled “Understanding addState() types”The method is annotated like this:
/** * @param {string} name * @param {new (services: GameServices) => State<unknown>} StateType */addState(name, StateType) {}Read the second parameter from left to right:
| Syntax | Meaning |
|---|---|
new (services: GameServices) => ... |
A class constructor that can be called with new and receives the shared services object. |
State<unknown> |
The constructor produces a State; its transition-props shape may differ from other registered states. |
StateType |
The parameter is the class itself, such as SettingsState, not new SettingsState(...). |
unknown is necessary because one game can register states with different props types. See State for props generics and State Machine for how states are handled.
The Game Loop
Section titled “The Game Loop”gameLoop() is a private implementation method. start() invokes it, so application code should not call it directly.
The browser passes requestAnimationFrame() a timestamp in milliseconds. Game subtracts the previous timestamp and divides by 1000, producing the seconds-based dt used by updates and timers. It then updates, renders, saves the timestamp, and schedules the next frame.