100 lines
2.6 KiB
JavaScript
100 lines
2.6 KiB
JavaScript
/**
|
|
* SceneManager.js
|
|
* Manages scene registration, switching, and lifecycle (enter/exit/update/render).
|
|
*/
|
|
|
|
class SceneManager {
|
|
constructor() {
|
|
/** @type {Map<string, object>} 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;
|