From 4ff5157f40bfbc3c59c13613fa594d463fc146be Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Sun, 19 Apr 2026 12:25:26 +0800 Subject: [PATCH] feat: add app init with auto scene discovery --- src/init.ts | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/init.ts diff --git a/src/init.ts b/src/init.ts new file mode 100644 index 0000000..c2a0e5a --- /dev/null +++ b/src/init.ts @@ -0,0 +1,99 @@ +import Game from "./core/Game"; +import SceneManager from "./scene/SceneManager"; +import { BaseScene } from "./scene/BaseScene"; +import { SceneType } from "./enums/SceneType"; +import { assetManager } from "./core/AssetManager"; +import { logger } from "./core/Logger"; +import eventBus from "./core/EventBus"; + +const game = Game.getInstance(); +const sceneManager = SceneManager.getInstance(); + +export async function initApp(): Promise { + await assetManager.init(); + await game.init(); + + // 自动导入所有场景文件 src/scenes/**/page_*.ts + const sceneModules = import.meta.glob("./scenes/**/page_*.ts", { eager: true }); + + for (const path in sceneModules) { + const mod = sceneModules[path]; + // 文件名匹配提取场景名称 + const match = path.match(/page_(.*?)\.ts$/); + if (!match) continue; + const sceneName = match[1]; + + const sceneClass = (mod as { default: Constructor }).default; + const scene = new sceneClass(); + + // 如果模块默认导出不是场景构造函数,尝试其他格式(兼容旧定义) + if (!scene || typeof scene !== "object" || !("stage" in scene)) { + logger.warn(`initApp: invalid scene file ${path}, skipping`); + continue; + } + + sceneManager.registerScene(scene); + } + + // 启动更新循环 + game.ticker.add((ticker) => { + const dt = ticker.deltaTime; + const current = sceneManager.currentScene; + + // 更新常驻场景 + sceneManager["scenes"].forEach((scene) => { + if (scene.type === SceneType.Resident && scene.stage.visible) { + scene.update?.(dt, ticker); + } + }); + + // 更新当前场景 + if (current) { + current.update?.(dt, ticker); + } + + game.render(); + + // lateUpdate + sceneManager["scenes"].forEach((scene) => { + if (scene.type === SceneType.Resident && scene.stage.visible && scene.lateUpdate) { + scene.lateUpdate(dt, ticker); + } + }); + + if (current?.lateUpdate) { + current.lateUpdate(dt, ticker); + } + }); + + // 处理常驻场景初始化 + const residentScenes: BaseScene[] = []; + sceneManager["scenes"].forEach((scene) => { + if (scene.type === SceneType.Resident) { + residentScenes.push(scene); + } + }); + + (async () => { + for (const scene of residentScenes) { + if (!scene._assetsLoaded) { + await scene.loadBundle?.(); + scene._assetsLoaded = true; + } + if (!scene._layoutDone) { + await scene.layout?.(); + scene._layoutDone = true; + } + await scene.onLoad?.(); + } + })(); + + // 场景变化监听 - 日志 + sceneManager.onStageChange((current) => { + logger.debug("Scene changed to", current.name); + }); + + logger.info("App initialized"); +} + +export { game, sceneManager, eventBus, assetManager, logger }; \ No newline at end of file