Skip to content

Latest commit

 

History

History
325 lines (253 loc) · 8.69 KB

File metadata and controls

325 lines (253 loc) · 8.69 KB

Game Module

Core game loop, Pipeline, GameObjects, and Scenes.

Overview

The game module provides the interactive layer of GCanvas. It manages the game loop, object lifecycle, input handling, and scene organization.

Quick Start

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();

Core Classes

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

Game Class

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

Key Properties

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

Key Methods

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

Pipeline Class

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

GameObject Class

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();
  }
}

Lifecycle Methods

Method When Called
update(dt) Every frame (if active)
render() Every frame (if visible)
destroy() When removed from pipeline

Input Events

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);
});

Scene Class

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 top

Scenes provide:

  • Hierarchical organization
  • Coordinate spaces
  • Z-ordering of children
  • Collective transforms

UI Components

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' }));

Input Access

// 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;
}

Events

// 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);

Architecture Diagram

┌─────────────────────────────────────────────────────────┐
│                         Game                             │
│  ┌────────────────────────────────────────────────────┐ │
│  │                     Pipeline                        │ │
│  │  ┌──────────────────────────────────────────────┐  │ │
│  │  │                    Scene                      │  │ │
│  │  │  ┌────────────┐  ┌────────────┐              │  │ │
│  │  │  │ GameObject │  │ GameObject │  ...         │  │ │
│  │  │  │  + Shape   │  │  + Shape   │              │  │ │
│  │  │  └────────────┘  └────────────┘              │  │ │
│  │  └──────────────────────────────────────────────┘  │ │
│  └────────────────────────────────────────────────────┘ │
│                           │                              │
│                           ▼                              │
│                    ┌────────────┐                        │
│                    │ Game Loop  │                        │
│                    │ update(dt) │                        │
│                    │ render()   │                        │
│                    └────────────┘                        │
└─────────────────────────────────────────────────────────┘

Related

See Also