/** * SceneManager.js * Manages scene registration, switching, and lifecycle (enter/exit/update/render). */ class SceneManager { constructor() { /** @type {Map} Registered scene instances */ this._scenes = new Map(); /** @type {object|null} Current active scene */ this._currentScene = null; /** @type {string|null} Current scene name */ this._currentName = null; /** @type {boolean} Whether a transition is in progress */ this._transitioning = false; } /** * Register a scene. * A scene object should implement: enter(params), exit(), update(dt), render(ctx). * @param {string} name - Unique scene name. * @param {object} scene - Scene instance. */ register(name, scene) { this._scenes.set(name, scene); } /** * Switch to a different scene. * @param {string} name - Target scene name. * @param {object} [params] - Optional parameters passed to the new scene's enter(). */ switchTo(name, params) { if (this._transitioning) return; if (!this._scenes.has(name)) { console.error(`[SceneManager] Scene "${name}" not registered.`); return; } this._transitioning = true; // Exit current scene if (this._currentScene && typeof this._currentScene.exit === 'function') { this._currentScene.exit(); } // Enter new scene this._currentName = name; this._currentScene = this._scenes.get(name); if (typeof this._currentScene.enter === 'function') { this._currentScene.enter(params || {}); } this._transitioning = false; } /** * Update the current scene. * @param {number} dt - Delta time in seconds. */ update(dt) { if (this._currentScene && typeof this._currentScene.update === 'function') { this._currentScene.update(dt); } } /** * Render the current scene. * @param {CanvasRenderingContext2D} ctx */ render(ctx) { if (this._currentScene && typeof this._currentScene.render === 'function') { this._currentScene.render(ctx); } } /** * Forward touch events to the current scene. * @param {string} eventType - 'touchstart' | 'touchmove' | 'touchend' * @param {TouchEvent} e */ handleTouch(eventType, e) { if (this._currentScene && typeof this._currentScene.handleTouch === 'function') { this._currentScene.handleTouch(eventType, e); } } /** Get the current scene name. */ get currentName() { return this._currentName; } /** Get the current scene instance. */ get currentScene() { return this._currentScene; } } module.exports = SceneManager;