import { BaseScene } from "./BaseScene"; import { SceneKeys } from "../SceneKeys"; import { AssetLoader, type AssetManifest } from "../utils/AssetLoader"; /** * 预加载场景。 * * 使用 HTML overlay 显示加载进度(CSS 动画,无需 Three.js 渲染)。 * 加载完成后自动切换到 Main 场景。 * * 要加载资源,在 getManifest() 中返回资源清单即可。 */ export class PreloaderScene extends BaseScene { private loader = new AssetLoader(); constructor() { super(SceneKeys.Preloader); } protected onEnter(): void { this.showOverlay(); this.startLoading(); } /** * 定义资源清单。按需添加资源条目。 * * 示例: * ```typescript * import logoTexture from "assets/images/logo.webp"; * import modelFile from "assets/models/character.glb"; * * return { * textures: [{ key: "logo", url: logoTexture }], * models: [{ key: "character", url: modelFile }], * }; * ``` */ protected getManifest(): AssetManifest { return {}; } private async startLoading(): Promise { const manifest = this.getManifest(); try { await this.loader.loadAll(manifest, (progress) => { this.updateProgress(progress); }); } catch (err) { console.error("[PreloaderScene] Loading failed:", err); } this.updateProgress(1); this.setLoadingText("Ready"); await this.delay(300); this.hideOverlay(); this.goToScene(SceneKeys.Main); } private showOverlay(): void { const overlay = document.getElementById("loading-overlay"); if (overlay) { overlay.classList.remove("hidden"); } } private hideOverlay(): void { const overlay = document.getElementById("loading-overlay"); if (overlay) { overlay.classList.add("hidden"); } } private updateProgress(value: number): void { const bar = document.getElementById("loading-bar"); if (bar) { bar.style.width = `${Math.round(value * 100)}%`; } } private setLoadingText(text: string): void { const el = document.getElementById("loading-text"); if (el) { el.textContent = text; } } private delay(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } }