feat: add Pokemon-style world mode with workshop integration

Two-mode game: explore a tile-based cyberpunk world, then enter
Workshop mode (the existing circuit editor) to craft components.

New modules (js/world/):
- sprites.js: programmatic pixel-art renderer (16x16 tiles, 3x scale)
- maps.js: tile-based map definitions (lab + town)
- worldState.js: player position, inventory, dialog, puzzle state
- worldRenderer.js: camera-following world renderer on shared canvas
- worldInput.js: WASD movement, E interaction, dialog system
- gameMode.js: central mode switcher (world ↔ workshop)

Changes to existing code:
- app.js: boots into world mode, registers circuit editor for workshop
- renderer.js: circuit draw loop now stoppable (start/stopCircuitLoop)
- index.html: added "Back to World" button for workshop mode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jose Luis
2026-03-20 15:52:13 +01:00
parent bbde11dfc7
commit e4cf35701e
9 changed files with 1903 additions and 14 deletions

View File

@@ -6,6 +6,8 @@ import { getGateLabel, drawWaveLabels, drawWaveforms } from './waveform.js';
import { getBusPairs } from './bus.js';
let canvas, ctx;
let circuitAnimFrameId = null;
let rendererInitialized = false;
/**
* Read the value arriving at an input port by looking up the source gate/port.
@@ -25,8 +27,23 @@ export function initRenderer() {
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
resize();
window.addEventListener('resize', resize);
requestAnimationFrame(draw);
if (!rendererInitialized) {
window.addEventListener('resize', resize);
rendererInitialized = true;
}
startCircuitLoop();
}
export function startCircuitLoop() {
if (circuitAnimFrameId) return; // already running
circuitAnimFrameId = requestAnimationFrame(draw);
}
export function stopCircuitLoop() {
if (circuitAnimFrameId) {
cancelAnimationFrame(circuitAnimFrameId);
circuitAnimFrameId = null;
}
}
export function resize() {
@@ -646,5 +663,5 @@ function draw() {
drawWaveforms();
}
requestAnimationFrame(draw);
circuitAnimFrameId = requestAnimationFrame(draw);
}