Interactive feature demos — click a tab to explore each module
Fixed-timestep game loop running at 60 FPS. Manages entities, scenes, and a camera with follow/shake support.
import { Game, Entity } from './src/engine.js';
const game = new Game();
game.init('canvas');
class Box extends Entity {
update(dt) { this.x += 100 * dt; }
render(ctx) {
ctx.fillStyle = '#0ff';
ctx.fillRect(this.x, this.y, 20, 20);
}
}
game.addEntity(new Box(0, 100, 20, 20));
game.start();
Tracks keyboard keys, mouse position/buttons, and touch events. Query key states per-frame.
import { InputManager } from './src/input.js';
const input = new InputManager(canvas);
// In your update loop:
if (input.isKeyDown('ArrowRight')) player.x += speed * dt;
if (input.isKeyPressed(' ')) player.jump();
const mouse = input.getMousePos();
input.endFrame(); // call at end of update
SpriteSheet frame extraction, frame-based Animation with play/loop, and AnimatedSprite for named animation sets.
import { SpriteSheet, Animation, AnimatedSprite } from './src/sprites.js';
const sheet = new SpriteSheet(image, 32, 32);
const walkFrames = sheet.getFrames(0, 4);
const anim = new Animation(walkFrames, 8, true);
const sprite = new AnimatedSprite();
sprite.add('walk', anim);
sprite.play('walk');
// In loop:
sprite.update(dt);
sprite.draw(ctx, x, y, 32, 32);
AABB, circle, and point tests. Collision response (separate, bounce). Spatial grid for broad-phase optimization.
import { rectVsRect, circleVsCircle, SpatialGrid } from './src/collision.js';
const hit = rectVsRect(
{ x: 10, y: 10, w: 50, h: 50 },
{ x: 40, y: 30, w: 50, h: 50 }
);
if (hit) console.log('Overlap:', hit.x, hit.y);
const grid = new SpatialGrid(64);
grid.insert(entityA);
const nearby = grid.retrieve(entityA);
Web Audio API wrapper with preloading, pooled playback, volume control, and mute toggle.
Audio requires user interaction and sound files to demo.
See the API code below for usage.
import { AudioManager } from './src/audio.js';
const audio = new AudioManager();
audio.init(); // call on first user click
await audio.load('shoot', 'sounds/shoot.wav');
await audio.load('music', 'sounds/bg.mp3');
audio.play('shoot'); // fire-and-forget
audio.play('music', true); // loop
audio.volume = 0.5;
audio.toggleMute();
Multi-layer tile rendering with camera offset, solid tile collision checking, and automatic viewport culling.
import { TileMap } from './src/tilemap.js';
const map = new TileMap(32, 32);
map.addLayer([
[1,0,0,1],
[1,0,0,1],
[1,1,1,1],
]);
map.setSolid(1);
// Check collision
const hits = map.checkCollision(px, py, pw, ph);
// Render with camera offset
map.render(ctx, camera.x, camera.y, 800, 600);