Core game loop, Pipeline, GameObjects, and Scenes.
The game module provides the interactive layer of GCanvas. It manages the game loop, object lifecycle, input handling, and scene organization.
import { Game, Scene, GameObject, Circle } from '@guinetik/gcanvas';
class Player extends GameObject {
constructor(game) {
super(game);
this.shape = new Circle(30, { color: 'blue' });
// Enable interactivity
this.interactive = true;
// Listen for click events
this.on('inputdown', (e) => {
console.log('Player clicked!');
});
}
update(dt) {
if (this.game.input.isKeyDown('ArrowRight')) {
this.shape.x += 200 * dt;
}
}
render() {
this.shape.draw();
}
}
class MyGame extends Game {
init() {
super.init();
this.enableFluidSize();
const scene = new Scene(this);
scene.add(new Player(this));
this.pipeline.add(scene);
}
}
const game = new MyGame(document.getElementById('canvas'));
game.start();| Class | Description |
|---|---|
| Game | Main loop, canvas management, input initialization |
| Pipeline | Manages object collections, update/render dispatch |
| GameObject | Base class for interactive entities |
| Scene | Hierarchical container for GameObjects |
The entry point for interactive applications.
class MyGame extends Game {
constructor(canvas) {
super(canvas);
this.enableFluidSize(); // Canvas fills viewport
this.backgroundColor = '#1a1a2e';
}
init() {
super.init(); // Initialize input systems
// Create scenes and objects
}
update(dt) {
super.update(dt); // Update pipeline
// Custom game logic
}
render() {
super.render(); // Render pipeline
// Custom rendering
}
}
const game = new MyGame(canvas);
game.setFPS(60); // Set target FPS
game.start(); // Begin game loop| Property | Type | Description |
|---|---|---|
canvas |
HTMLCanvasElement |
The canvas element |
ctx |
CanvasRenderingContext2D |
2D context |
pipeline |
Pipeline |
Object manager |
events |
EventEmitter |
Event system |
width |
number |
Canvas width |
height |
number |
Canvas height |
running |
boolean |
Is loop running? |
dt |
number |
Last delta time |
| Method | Description |
|---|---|
start() |
Begin the game loop |
stop() |
Stop the game loop |
init() |
Initialize game (override) |
update(dt) |
Update logic (override) |
render() |
Render logic (override) |
enableFluidSize() |
Auto-resize to window |
setFPS(fps) |
Set target frame rate |
enablePauseOnBlur(bool) |
Pause when tab loses focus |
Manages collections of objects for update and render.
// Add objects
game.pipeline.add(scene);
game.pipeline.add(gameObject);
// Remove objects
game.pipeline.remove(object);
// Clear all
game.pipeline.clear();Pipeline automatically:
- Calls
update(dt)on active objects - Calls
render()on visible objects - Sorts by zIndex
- Dispatches input events
Base class for all interactive entities.
class Enemy extends GameObject {
constructor(game) {
super(game);
this.shape = new Rectangle({ width: 40, height: 40, color: 'red' });
this.speed = 100;
// Enable interactivity
this.interactive = true;
// Listen for input events using event emitter pattern
this.on('inputdown', (e) => {
console.log('Enemy clicked!');
});
this.on('inputup', (e) => { });
this.on('inputmove', (e) => { });
this.on('mouseover', () => { });
this.on('mouseout', () => { });
}
update(dt) {
this.shape.x += this.speed * dt;
}
render() {
this.shape.draw();
}
}| Method | When Called |
|---|---|
update(dt) |
Every frame (if active) |
render() |
Every frame (if visible) |
destroy() |
When removed from pipeline |
GameObjects use the event emitter pattern for input handling. First, set interactive = true, then use .on(eventName, callback):
| Event | When Fired |
|---|---|
inputdown |
Click/tap start |
inputup |
Click/tap end |
inputmove |
Pointer movement over the object |
mouseover |
Hover enter |
mouseout |
Hover leave |
click |
Click/tap (after inputup) |
Example:
this.interactive = true;
this.on('inputdown', (e) => {
console.log('Clicked at', e.x, e.y);
});Hierarchical container for GameObjects.
const gameScene = new Scene(game);
const uiScene = new Scene(game);
// Add objects to scenes
gameScene.add(player);
gameScene.add(enemy);
uiScene.add(healthBar);
uiScene.add(scoreDisplay);
// Add scenes to pipeline (order matters)
game.pipeline.add(gameScene); // Rendered first
game.pipeline.add(uiScene); // Rendered on topScenes provide:
- Hierarchical organization
- Coordinate spaces
- Z-ordering of children
- Collective transforms
Built on GameObject and Scene:
| Component | Description |
|---|---|
Button |
Clickable with visual states |
ToggleButton |
On/off toggle |
Cursor |
Custom cursor |
FPSCounter |
FPS display |
import { Button, FPSCounter } from '@guinetik/gcanvas';
const button = new Button(game, 'Click Me', {
x: 400,
y: 300
});
button.on('click', () => {
console.log('Clicked!');
});
scene.add(button);
scene.add(new FPSCounter(game, { anchor: 'bottom-right' }));// In GameObject or Game
update(dt) {
// Keyboard
if (this.game.input.isKeyDown('ArrowLeft')) { }
if (this.game.input.isKeyDown('Space')) { }
if (this.game.input.isKeyDown('KeyW')) { }
// Mouse position
const mx = this.game.mouse.x;
const my = this.game.mouse.y;
}// Custom events
game.events.on('player-died', (data) => {
console.log('Player died:', data);
});
game.events.emit('player-died', { score: 100 });
// Remove listener
game.events.off('player-died', handler);┌─────────────────────────────────────────────────────────┐
│ Game │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Pipeline │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Scene │ │ │
│ │ │ ┌────────────┐ ┌────────────┐ │ │ │
│ │ │ │ GameObject │ │ GameObject │ ... │ │ │
│ │ │ │ + Shape │ │ + Shape │ │ │ │
│ │ │ └────────────┘ └────────────┘ │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ Game Loop │ │
│ │ update(dt) │ │
│ │ render() │ │
│ └────────────┘ │
└─────────────────────────────────────────────────────────┘
- Game Lifecycle - Update/render cycle
- Two-Layer Architecture - Shape vs Game layer
- First Game Guide
- Shapes Module
- IO Module - Input handling
- Motion Module - Animation