From 6e48f225407c690adbecdc4fcaa3de7cfce6c13e Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Sat, 11 Oct 2025 11:33:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0v2.2.1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.vitepress/config.mjs | 9 +- docs/guide/scene-manager.md | 675 ++++++++++++++++++++++++++++++++ docs/guide/scene.md | 402 +++++++++++-------- docs/guide/world-manager.md | 761 ++++++++++++++++++++++++++++++++++++ 4 files changed, 1687 insertions(+), 160 deletions(-) create mode 100644 docs/guide/scene-manager.md create mode 100644 docs/guide/world-manager.md diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index 4f834714..7e264b04 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -73,7 +73,14 @@ export default defineConfig({ { text: 'Worker系统 (多线程)', link: '/guide/worker-system' } ] }, - { text: '场景管理 (Scene)', link: '/guide/scene' }, + { + text: '场景管理 (Scene)', + link: '/guide/scene', + items: [ + { text: 'SceneManager', link: '/guide/scene-manager' }, + { text: 'WorldManager', link: '/guide/world-manager' } + ] + }, { text: '序列化系统 (Serialization)', link: '/guide/serialization' }, { text: '事件系统 (Event)', link: '/guide/event-system' }, { text: '时间和定时器 (Time)', link: '/guide/time-and-timers' }, diff --git a/docs/guide/scene-manager.md b/docs/guide/scene-manager.md new file mode 100644 index 00000000..8c8e910a --- /dev/null +++ b/docs/guide/scene-manager.md @@ -0,0 +1,675 @@ +# SceneManager + +SceneManager 是 ECS Framework 提供的轻量级场景管理器,适用于 95% 的游戏应用。它提供简单直观的 API,支持场景切换和延迟加载。 + +## 适用场景 + +SceneManager 适合以下场景: +- 单人游戏 +- 简单多人游戏 +- 移动游戏 +- 需要场景切换的游戏(菜单、游戏、暂停等) +- 不需要多 World 隔离的项目 + +## 特点 + +- 轻量级,零额外开销 +- 简单直观的 API +- 支持延迟场景切换(避免在当前帧中途切换) +- 自动管理 ECS 流式 API +- 自动处理场景生命周期 +- 集成在 Core 中,自动更新 + +## 基本使用 + +### 推荐方式:使用 Core 的静态方法 + +这是最简单和推荐的方式,适合大多数应用: + +```typescript +import { Core, Scene } from '@esengine/ecs-framework'; + +// 1. 初始化 Core +Core.create({ debug: true }); + +// 2. 创建并设置场景 +class GameScene extends Scene { + protected initialize(): void { + this.name = "GameScene"; + + // 添加系统 + this.addSystem(new MovementSystem()); + this.addSystem(new RenderSystem()); + + // 创建初始实体 + const player = this.createEntity("Player"); + player.addComponent(new Transform(400, 300)); + player.addComponent(new Health(100)); + } + + public onStart(): void { + console.log("游戏场景已启动"); + } +} + +// 3. 设置场景 +Core.setScene(new GameScene()); + +// 4. 游戏循环(Core.update 会自动更新场景) +function gameLoop(deltaTime: number) { + Core.update(deltaTime); // 自动更新所有服务和场景 +} + +// Laya 引擎集成 +Laya.timer.frameLoop(1, this, () => { + const deltaTime = Laya.timer.delta / 1000; + Core.update(deltaTime); +}); + +// Cocos Creator 集成 +update(deltaTime: number) { + Core.update(deltaTime); +} +``` + +### 高级方式:直接使用 SceneManager + +如果需要更多控制,可以直接使用 SceneManager: + +```typescript +import { Core, SceneManager, Scene } from '@esengine/ecs-framework'; + +// 初始化 Core +Core.create({ debug: true }); + +// 获取 SceneManager(Core 已自动创建并注册) +const sceneManager = Core.services.resolve(SceneManager); + +// 设置场景 +const gameScene = new GameScene(); +sceneManager.setScene(gameScene); + +// 游戏循环(仍然使用 Core.update) +function gameLoop(deltaTime: number) { + Core.update(deltaTime); // Core会自动调用sceneManager.update() +} +``` + +**重要**:无论使用哪种方式,游戏循环中都应该只调用 `Core.update()`,它会自动更新 SceneManager 和场景。不需要手动调用 `sceneManager.update()`。 + +## 场景切换 + +### 立即切换 + +使用 `Core.setScene()` 或 `sceneManager.setScene()` 立即切换场景: + +```typescript +// 方式1:使用 Core(推荐) +Core.setScene(new MenuScene()); + +// 方式2:使用 SceneManager +const sceneManager = Core.services.resolve(SceneManager); +sceneManager.setScene(new MenuScene()); +``` + +### 延迟切换 + +使用 `Core.loadScene()` 或 `sceneManager.loadScene()` 延迟切换场景,场景会在下一帧切换: + +```typescript +// 方式1:使用 Core(推荐) +Core.loadScene(new GameOverScene()); + +// 方式2:使用 SceneManager +const sceneManager = Core.services.resolve(SceneManager); +sceneManager.loadScene(new GameOverScene()); +``` + +在 System 中切换场景时,应该使用延迟切换: + +```typescript +class GameOverSystem extends EntitySystem { + process(entities: readonly Entity[]): void { + const player = entities.find(e => e.name === 'Player'); + const health = player?.getComponent(Health); + + if (health && health.value <= 0) { + // 延迟切换到游戏结束场景(下一帧生效) + Core.loadScene(new GameOverScene()); + // 当前帧继续执行,不会中断当前系统的处理 + } + } +} +``` + +### 完整的场景切换示例 + +```typescript +import { Core, Scene } from '@esengine/ecs-framework'; + +// 初始化 +Core.create({ debug: true }); + +// 菜单场景 +class MenuScene extends Scene { + protected initialize(): void { + this.name = "MenuScene"; + + // 监听开始游戏事件 + this.eventSystem.on('start_game', () => { + Core.loadScene(new GameScene()); + }); + } + + public onStart(): void { + console.log("显示菜单界面"); + } + + public unload(): void { + console.log("菜单场景卸载"); + } +} + +// 游戏场景 +class GameScene extends Scene { + protected initialize(): void { + this.name = "GameScene"; + + // 创建游戏实体 + const player = this.createEntity("Player"); + player.addComponent(new Transform(400, 300)); + player.addComponent(new Health(100)); + + // 监听游戏结束事件 + this.eventSystem.on('game_over', () => { + Core.loadScene(new GameOverScene()); + }); + } + + public onStart(): void { + console.log("游戏开始"); + } + + public unload(): void { + console.log("游戏场景卸载"); + } +} + +// 游戏结束场景 +class GameOverScene extends Scene { + protected initialize(): void { + this.name = "GameOverScene"; + + // 监听返回菜单事件 + this.eventSystem.on('back_to_menu', () => { + Core.loadScene(new MenuScene()); + }); + } + + public onStart(): void { + console.log("显示游戏结束界面"); + } +} + +// 开始游戏 +Core.setScene(new MenuScene()); + +// 游戏循环 +function gameLoop(deltaTime: number) { + Core.update(deltaTime); // 自动更新场景 +} +``` + +## API 参考 + +### Core 静态方法(推荐) + +#### Core.setScene() + +立即切换场景。 + +```typescript +public static setScene(scene: T): T +``` + +**参数**: +- `scene` - 要设置的场景实例 + +**返回**: +- 返回设置的场景实例 + +**示例**: +```typescript +const gameScene = Core.setScene(new GameScene()); +console.log(gameScene.name); +``` + +#### Core.loadScene() + +延迟加载场景(下一帧切换)。 + +```typescript +public static loadScene(scene: T): void +``` + +**参数**: +- `scene` - 要加载的场景实例 + +**示例**: +```typescript +Core.loadScene(new GameOverScene()); +``` + +#### Core.scene + +获取当前活跃的场景。 + +```typescript +public static get scene(): IScene | null +``` + +**返回**: +- 当前场景实例,如果没有场景则返回 null + +**示例**: +```typescript +const currentScene = Core.scene; +if (currentScene) { + console.log(`当前场景: ${currentScene.name}`); +} +``` + +#### Core.ecsAPI + +获取 ECS 流式 API。 + +```typescript +public static get ecsAPI(): ECSFluentAPI | null +``` + +**返回**: +- ECS API 实例,如果当前没有场景则返回 null + +**示例**: +```typescript +const api = Core.ecsAPI; +if (api) { + // 查询实体 + const enemies = api.find(Enemy, Transform); + + // 发射事件 + api.emit('game:start', { level: 1 }); +} +``` + +### SceneManager 方法(高级) + +如果需要直接使用 SceneManager,可以通过服务容器获取: + +```typescript +const sceneManager = Core.services.resolve(SceneManager); +``` + +#### setScene() + +立即切换场景。 + +```typescript +public setScene(scene: T): T +``` + +#### loadScene() + +延迟加载场景。 + +```typescript +public loadScene(scene: T): void +``` + +#### currentScene + +获取当前场景。 + +```typescript +public get currentScene(): IScene | null +``` + +#### api + +获取 ECS 流式 API。 + +```typescript +public get api(): ECSFluentAPI | null +``` + +#### hasScene + +检查是否有活跃场景。 + +```typescript +public get hasScene(): boolean +``` + +#### hasPendingScene + +检查是否有待切换的场景。 + +```typescript +public get hasPendingScene(): boolean +``` + +## 使用 ECS 流式 API + +通过 `Core.ecsAPI` 可以方便地访问场景的 ECS 功能: + +```typescript +const api = Core.ecsAPI; +if (!api) { + console.error('没有活跃场景'); + return; +} + +// 查询实体 +const players = api.find(Player, Transform); +const enemies = api.find(Enemy, Health, Transform); + +// 发射事件 +api.emit('player:scored', { points: 100 }); + +// 监听事件 +api.on('enemy:died', (data) => { + console.log('敌人死亡:', data); +}); +``` + +## 最佳实践 + +### 1. 使用 Core 的静态方法 + +```typescript +// 推荐:使用 Core 的静态方法 +Core.setScene(new GameScene()); +Core.loadScene(new MenuScene()); +const currentScene = Core.scene; + +// 不推荐:除非有特殊需求,否则不需要直接使用 SceneManager +const sceneManager = Core.services.resolve(SceneManager); +sceneManager.setScene(new GameScene()); +``` + +### 2. 只调用 Core.update() + +```typescript +// 正确:只调用 Core.update() +function gameLoop(deltaTime: number) { + Core.update(deltaTime); // 自动更新所有服务和场景 +} + +// 错误:不要手动调用 sceneManager.update() +function gameLoop(deltaTime: number) { + Core.update(deltaTime); + sceneManager.update(); // 重复更新,会导致问题! +} +``` + +### 3. 使用延迟切换避免问题 + +在 System 中切换场景时,应该使用 `loadScene()` 而不是 `setScene()`: + +```typescript +// 推荐:延迟切换 +class HealthSystem extends EntitySystem { + process(entities: readonly Entity[]): void { + for (const entity of entities) { + const health = entity.getComponent(Health); + if (health.value <= 0) { + Core.loadScene(new GameOverScene()); + // 当前帧继续处理其他实体 + } + } + } +} + +// 不推荐:立即切换可能导致问题 +class HealthSystem extends EntitySystem { + process(entities: readonly Entity[]): void { + for (const entity of entities) { + const health = entity.getComponent(Health); + if (health.value <= 0) { + Core.setScene(new GameOverScene()); + // 场景立即切换,当前帧的其他实体可能无法正常处理 + } + } + } +} +``` + +### 4. 场景职责分离 + +每个场景应该只负责一个特定的游戏状态: + +```typescript +// 好的设计 - 职责清晰 +class MenuScene extends Scene { + // 只处理菜单相关逻辑 +} + +class GameScene extends Scene { + // 只处理游戏玩法逻辑 +} + +class PauseScene extends Scene { + // 只处理暂停界面逻辑 +} + +// 避免的设计 - 职责混乱 +class MegaScene extends Scene { + // 包含菜单、游戏、暂停等所有逻辑 +} +``` + +### 5. 资源管理 + +在场景的 `unload()` 方法中清理资源: + +```typescript +class GameScene extends Scene { + private textures: Map = new Map(); + private sounds: Map = new Map(); + + protected initialize(): void { + this.loadResources(); + } + + private loadResources(): void { + this.textures.set('player', loadTexture('player.png')); + this.sounds.set('bgm', loadSound('bgm.mp3')); + } + + public unload(): void { + // 清理资源 + this.textures.clear(); + this.sounds.clear(); + console.log('场景资源已清理'); + } +} +``` + +### 6. 事件驱动的场景切换 + +使用事件系统来触发场景切换,保持代码解耦: + +```typescript +class GameScene extends Scene { + protected initialize(): void { + // 监听场景切换事件 + this.eventSystem.on('goto:menu', () => { + Core.loadScene(new MenuScene()); + }); + + this.eventSystem.on('goto:gameover', (data) => { + Core.loadScene(new GameOverScene()); + }); + } +} + +// 在 System 中触发事件 +class GameLogicSystem extends EntitySystem { + process(entities: readonly Entity[]): void { + if (levelComplete) { + this.scene.eventSystem.emitSync('goto:gameover', { + score: 1000, + level: 5 + }); + } + } +} +``` + +## 架构层次 + +SceneManager 在 ECS Framework 中的位置: + +``` +Core (全局服务) + └── SceneManager (场景管理,自动更新) + └── Scene (当前场景) + ├── EntitySystem (系统) + ├── Entity (实体) + └── Component (组件) +``` + +## 与 WorldManager 的对比 + +| 特性 | SceneManager | WorldManager | +|------|--------------|--------------| +| 适用场景 | 95% 的游戏应用 | 高级多世界隔离场景 | +| 复杂度 | 简单 | 复杂 | +| 场景数量 | 单场景(可切换) | 多 World,每个 World 多场景 | +| 性能开销 | 最小 | 较高 | +| 使用方式 | `Core.setScene()` | `worldManager.createWorld()` | + +**何时使用 SceneManager**: +- 单人游戏 +- 简单的多人游戏 +- 移动游戏 +- 场景之间需要切换但不需要同时运行 + +**何时使用 WorldManager**: +- MMO 游戏服务器(每个房间一个 World) +- 游戏大厅系统(每个游戏房间完全隔离) +- 需要运行多个完全独立的游戏实例 + +## 完整示例 + +```typescript +import { Core, Scene, EntitySystem, Entity, Matcher } from '@esengine/ecs-framework'; + +// 定义组件 +class Transform { + constructor(public x: number, public y: number) {} +} + +class Velocity { + constructor(public vx: number, public vy: number) {} +} + +class Health { + constructor(public value: number) {} +} + +// 定义系统 +class MovementSystem extends EntitySystem { + constructor() { + super(Matcher.all(Transform, Velocity)); + } + + process(entities: readonly Entity[]): void { + for (const entity of entities) { + const transform = entity.getComponent(Transform); + const velocity = entity.getComponent(Velocity); + + if (transform && velocity) { + transform.x += velocity.vx; + transform.y += velocity.vy; + } + } + } +} + +// 定义场景 +class MenuScene extends Scene { + protected initialize(): void { + this.name = "MenuScene"; + console.log("菜单场景初始化"); + } + + public onStart(): void { + console.log("菜单场景启动"); + } +} + +class GameScene extends Scene { + protected initialize(): void { + this.name = "GameScene"; + + // 添加系统 + this.addSystem(new MovementSystem()); + + // 创建玩家 + const player = this.createEntity("Player"); + player.addComponent(new Transform(400, 300)); + player.addComponent(new Velocity(0, 0)); + player.addComponent(new Health(100)); + + // 创建敌人 + for (let i = 0; i < 5; i++) { + const enemy = this.createEntity(`Enemy_${i}`); + enemy.addComponent(new Transform( + Math.random() * 800, + Math.random() * 600 + )); + enemy.addComponent(new Velocity( + Math.random() * 100 - 50, + Math.random() * 100 - 50 + )); + enemy.addComponent(new Health(50)); + } + } + + public onStart(): void { + console.log('游戏场景启动'); + } + + public unload(): void { + console.log('游戏场景卸载'); + } +} + +// 初始化 +Core.create({ debug: true }); + +// 设置初始场景 +Core.setScene(new MenuScene()); + +// 游戏循环 +let lastTime = 0; +function gameLoop(currentTime: number) { + const deltaTime = (currentTime - lastTime) / 1000; + lastTime = currentTime; + + // 只需要调用 Core.update,它会自动更新场景 + Core.update(deltaTime); + + requestAnimationFrame(gameLoop); +} + +requestAnimationFrame(gameLoop); + +// 切换到游戏场景 +setTimeout(() => { + Core.loadScene(new GameScene()); +}, 3000); +``` + +SceneManager 为大多数游戏提供了简单而强大的场景管理能力。通过 Core 的静态方法,你可以轻松地管理场景切换。如果你需要更高级的多世界隔离功能,请参考 [WorldManager](./world-manager.md) 文档。 diff --git a/docs/guide/scene.md b/docs/guide/scene.md index a263a392..2be6a2a1 100644 --- a/docs/guide/scene.md +++ b/docs/guide/scene.md @@ -11,6 +11,22 @@ - 事件系统支持 - 性能监控和调试信息 +## 场景管理方式 + +ECS Framework 提供了两种场景管理方式: + +1. **[SceneManager](./scene-manager.md)** - 适用于 95% 的游戏应用 + - 单人游戏、简单多人游戏、移动游戏 + - 轻量级,简单直观的 API + - 支持场景切换 + +2. **[WorldManager](./world-manager.md)** - 适用于高级多世界隔离场景 + - MMO 游戏服务器、游戏房间系统 + - 多 World 管理,每个 World 可包含多个场景 + - 完全隔离的独立环境 + +本文档重点介绍 Scene 类本身的使用方法。关于场景管理器的详细信息,请查看对应的文档。 + ## 创建场景 ### 继承 Scene 类 @@ -106,6 +122,13 @@ const scene = new ExampleScene(); // 场景的 initialize(), begin(), update(), end() 由框架自动调用 ``` +**生命周期方法**: + +1. `initialize()` - 场景初始化,设置系统和初始实体 +2. `begin()` / `onStart()` - 场景开始运行 +3. `update()` - 每帧更新(由场景管理器调用) +4. `end()` / `unload()` - 场景卸载,清理资源 + ## 实体管理 ### 创建实体 @@ -247,15 +270,42 @@ class EventScene extends Scene { } public triggerGameEvent(): void { - // 发送事件 + // 发送事件(同步) this.eventSystem.emitSync('custom_event', { message: "这是自定义事件", timestamp: Date.now() }); + + // 发送事件(异步) + this.eventSystem.emit('async_event', { + data: "异步事件数据" + }); } } ``` +### 事件系统 API + +```typescript +// 监听事件 +this.eventSystem.on('event_name', callback); + +// 监听一次(自动取消订阅) +this.eventSystem.once('event_name', callback); + +// 取消监听 +this.eventSystem.off('event_name', callback); + +// 同步发送事件 +this.eventSystem.emitSync('event_name', data); + +// 异步发送事件 +this.eventSystem.emit('event_name', data); + +// 清除所有事件监听 +this.eventSystem.clear(); +``` + ## 场景统计和调试 ### 获取场景统计 @@ -287,176 +337,58 @@ class StatsScene extends Scene { } ``` -## 场景集成到框架 +## 组件查询 -ECS Framework 提供了灵活的场景管理架构,适用于不同规模的应用: - -### 1. 使用 SceneManager(推荐大多数应用) - -适用于 95% 的游戏应用(单人游戏、简单多人游戏、移动游戏等): +Scene 提供了强大的组件查询系统: ```typescript -import { Core, Scene, SceneManager } from '@esengine/ecs-framework'; - -// 初始化Core(全局服务) -Core.create({ debug: true }); - -// 从服务容器获取 SceneManager(Core 已自动创建并注册) -const sceneManager = Core.services.resolve(SceneManager); - -// 创建游戏场景 -class GameScene extends Scene { +class QueryScene extends Scene { protected initialize(): void { - this.name = "GameScene"; - this.addSystem(new MovementSystem()); - this.addSystem(new RenderSystem()); - } -} - -// 设置场景 -const gameScene = new GameScene(); -sceneManager.setScene(gameScene); - -// 游戏循环 -function gameLoop(deltaTime: number) { - Core.update(deltaTime); // 更新全局服务 - sceneManager.update(); // 更新当前场景 -} -``` - -### 2. 场景切换 - -SceneManager 支持流畅的场景切换: - -```typescript -// 立即切换场景 -const menuScene = new MenuScene(); -sceneManager.setScene(menuScene); - -// 延迟切换场景(在下一帧切换) -const gameScene = new GameScene(); -sceneManager.startSceneTransition(gameScene, false); - -// 访问当前场景 -const currentScene = sceneManager.currentScene; - -// 访问 ECS API -const ecsAPI = sceneManager.ecsAPI; -const entity = ecsAPI?.createEntity('player'); -``` - -### 3. 使用 WorldManager(高级用例) - -适用于需要完全隔离的多世界应用(MMO服务器、游戏房间系统等): - -```typescript -import { Core, WorldManager } from '@esengine/ecs-framework'; - -// 初始化Core(全局服务) -Core.create({ debug: true }); - -// 从服务容器获取 WorldManager(Core 已自动创建并注册) -const worldManager = Core.services.resolve(WorldManager); - -// 创建多个独立的游戏世界 -const gameWorld = worldManager.createWorld('game', { - name: 'MainGame', - maxScenes: 5 -}); - -// 在World中创建场景 -const menuScene = gameWorld.createScene('menu', new MenuScene()); -const gameScene = gameWorld.createScene('game', new GameScene()); - -// 激活场景 -gameWorld.setSceneActive('menu', true); - -// 游戏循环 -function gameLoop(deltaTime: number) { - Core.update(deltaTime); // 更新全局服务 - worldManager.updateAll(); // 更新所有世界 -} -``` - -## 多场景管理 - -在World中可以管理多个场景,通过激活/停用来切换: - -```typescript -class GameWorld extends World { - private menuScene: Scene; - private gameScene: Scene; - private gameOverScene: Scene; - - public initialize(): void { - // 创建多个场景 - this.menuScene = this.createScene('menu', new MenuScene()); - this.gameScene = this.createScene('game', new GameScene()); - this.gameOverScene = this.createScene('gameover', new GameOverScene()); - - // 设置初始场景 - this.showMenu(); + // 创建一些实体 + for (let i = 0; i < 10; i++) { + const entity = this.createEntity(`Entity_${i}`); + entity.addComponent(new Transform(i * 10, 0)); + entity.addComponent(new Velocity(1, 0)); + if (i % 2 === 0) { + entity.addComponent(new Renderer()); + } + } } - public showMenu(): void { - this.deactivateAllScenes(); - this.setSceneActive('menu', true); - } + public queryEntities(): void { + // 通过 QuerySystem 查询 + const entities = this.querySystem.query([Transform, Velocity]); + console.log(`找到 ${entities.length} 个有 Transform 和 Velocity 的实体`); - public startGame(): void { - this.deactivateAllScenes(); - this.setSceneActive('game', true); - } - - public showGameOver(): void { - this.deactivateAllScenes(); - this.setSceneActive('gameover', true); - } - - private deactivateAllScenes(): void { - this.setSceneActive('menu', false); - this.setSceneActive('game', false); - this.setSceneActive('gameover', false); + // 使用 ECS 流式 API(如果通过 SceneManager) + // const api = sceneManager.api; + // const entities = api?.find(Transform, Velocity); } } ``` -## 架构层次 +## 性能监控 -ECS Framework 的架构层次清晰,职责分明: +Scene 内置了性能监控功能: ```typescript -// 架构层次: -// Core (全局服务) → SceneManager (场景管理) → Scene → EntitySystem → Entity → Component -// 或 -// Core (全局服务) → WorldManager (世界管理) → World → Scene → EntitySystem → Entity → Component +class PerformanceScene extends Scene { + public showPerformance(): void { + // 获取性能数据 + const perfData = this.performanceMonitor?.getPerformanceData(); + if (perfData) { + console.log('FPS:', perfData.fps); + console.log('帧时间:', perfData.frameTime); + console.log('实体更新时间:', perfData.entityUpdateTime); + console.log('系统更新时间:', perfData.systemUpdateTime); + } -// 1. 推荐:使用 SceneManager 管理单场景/场景切换 -import { Core, SceneManager } from '@esengine/ecs-framework'; - -Core.create({ debug: true }); -const sceneManager = Core.services.resolve(SceneManager); -sceneManager.setScene(new GameScene()); - -// 游戏循环 -function gameLoop(deltaTime: number) { - Core.update(deltaTime); // 全局服务 - sceneManager.update(); // 场景更新 -} - -// 2. 高级:使用 WorldManager 管理多世界 -import { Core, WorldManager } from '@esengine/ecs-framework'; - -Core.create({ debug: true }); -const worldManager = Core.services.resolve(WorldManager); -const world = worldManager.createWorld('gameWorld'); -const scene = world.createScene('mainScene', new GameScene()); -world.setSceneActive('mainScene', true); - -// 游戏循环 -function gameLoop(deltaTime: number) { - Core.update(deltaTime); // 全局服务 - worldManager.updateAll(); // 所有世界更新 + // 获取性能报告 + const report = this.performanceMonitor?.generateReport(); + if (report) { + console.log('性能报告:', report); + } + } } ``` @@ -465,7 +397,7 @@ function gameLoop(deltaTime: number) { ### 1. 场景职责分离 ```typescript -// ✅ 好的场景设计 - 职责清晰 +// 好的场景设计 - 职责清晰 class MenuScene extends Scene { // 只处理菜单相关逻辑 } @@ -478,7 +410,7 @@ class InventoryScene extends Scene { // 只处理物品栏逻辑 } -// ❌ 避免的场景设计 - 职责混乱 +// 避免的场景设计 - 职责混乱 class MegaScene extends Scene { // 包含菜单、游戏、物品栏等所有逻辑 } @@ -525,12 +457,25 @@ class ResourceScene extends Scene { private loadResources(): void { // 加载场景所需资源 + this.textures.set('player', this.loadTexture('player.png')); + this.sounds.set('bgm', this.loadSound('bgm.mp3')); } public unload(): void { // 清理资源 this.textures.clear(); this.sounds.clear(); + console.log('场景资源已清理'); + } + + private loadTexture(path: string): any { + // 加载纹理 + return null; + } + + private loadSound(path: string): any { + // 加载音效 + return null; } } ``` @@ -571,7 +516,146 @@ class EventHandlingScene extends Scene { private onPlayerInput(data: any): void { // 处理玩家输入 } + + public unload(): void { + // 清理事件监听 + this.eventSystem.clear(); + } } ``` -场景是 ECS 框架的核心容器,正确使用场景管理能让你的游戏架构更加清晰、模块化和易于维护。 \ No newline at end of file +### 5. 初始化顺序 + +```typescript +class ProperInitScene extends Scene { + protected initialize(): void { + // 1. 首先设置场景配置 + this.name = "GameScene"; + + // 2. 然后添加系统(按依赖顺序) + this.addSystem(new InputSystem()); + this.addSystem(new MovementSystem()); + this.addSystem(new PhysicsSystem()); + this.addSystem(new RenderSystem()); + + // 3. 最后创建实体 + this.createEntities(); + + // 4. 设置事件监听 + this.setupEvents(); + } + + private createEntities(): void { + // 创建实体 + } + + private setupEvents(): void { + // 设置事件监听 + } +} +``` + +## 完整示例 + +```typescript +import { Scene, EntitySystem, Entity, Matcher } from '@esengine/ecs-framework'; + +// 定义组件 +class Transform { + constructor(public x: number, public y: number) {} +} + +class Velocity { + constructor(public vx: number, public vy: number) {} +} + +class Health { + constructor(public value: number) {} +} + +// 定义系统 +class MovementSystem extends EntitySystem { + constructor() { + super(Matcher.all(Transform, Velocity)); + } + + process(entities: readonly Entity[]): void { + for (const entity of entities) { + const transform = entity.getComponent(Transform); + const velocity = entity.getComponent(Velocity); + + if (transform && velocity) { + transform.x += velocity.vx; + transform.y += velocity.vy; + } + } + } +} + +// 定义场景 +class GameScene extends Scene { + protected initialize(): void { + this.name = "GameScene"; + + // 添加系统 + this.addSystem(new MovementSystem()); + + // 创建玩家 + const player = this.createEntity("Player"); + player.addComponent(new Transform(400, 300)); + player.addComponent(new Velocity(0, 0)); + player.addComponent(new Health(100)); + + // 创建敌人 + for (let i = 0; i < 5; i++) { + const enemy = this.createEntity(`Enemy_${i}`); + enemy.addComponent(new Transform( + Math.random() * 800, + Math.random() * 600 + )); + enemy.addComponent(new Velocity( + Math.random() * 100 - 50, + Math.random() * 100 - 50 + )); + enemy.addComponent(new Health(50)); + } + + // 设置事件监听 + this.eventSystem.on('player_died', () => { + console.log('玩家死亡!'); + }); + } + + public onStart(): void { + console.log('游戏场景启动'); + } + + public unload(): void { + console.log('游戏场景卸载'); + this.eventSystem.clear(); + } +} + +// 使用场景 +// 方式1:通过 SceneManager(推荐) +import { Core, SceneManager } from '@esengine/ecs-framework'; + +Core.create({ debug: true }); +const sceneManager = Core.services.resolve(SceneManager); +sceneManager.setScene(new GameScene()); + +// 方式2:通过 WorldManager(高级用例) +import { WorldManager } from '@esengine/ecs-framework'; + +const worldManager = Core.services.resolve(WorldManager); +const world = worldManager.createWorld('game'); +world.createScene('main', new GameScene()); +world.setSceneActive('main', true); +``` + +## 下一步 + +- 了解 [SceneManager](./scene-manager.md) - 适用于大多数游戏的简单场景管理 +- 了解 [WorldManager](./world-manager.md) - 适用于需要多世界隔离的高级场景 + +场景是 ECS 框架的核心容器,正确使用场景管理能让你的游戏架构更加清晰、模块化和易于维护。 diff --git a/docs/guide/world-manager.md b/docs/guide/world-manager.md new file mode 100644 index 00000000..9d378a67 --- /dev/null +++ b/docs/guide/world-manager.md @@ -0,0 +1,761 @@ +# WorldManager + +WorldManager 是 ECS Framework 提供的高级世界管理器,用于管理多个完全隔离的游戏世界(World)。每个 World 都是独立的 ECS 环境,可以包含多个场景。 + +## 适用场景 + +WorldManager 适合以下高级场景: +- MMO 游戏服务器的多房间管理 +- 游戏大厅系统(每个游戏房间完全隔离) +- 服务器端的多游戏实例 +- 需要完全隔离的多个游戏环境 +- 需要同时运行多个独立世界的应用 + +## 特点 + +- 多 World 管理,每个 World 完全独立 +- 每个 World 可以包含多个 Scene +- 支持 World 的激活/停用 +- 自动清理空 World +- World 级别的全局系统 +- 批量操作和查询 + +## 基本使用 + +### 初始化 + +WorldManager 是 Core 的内置服务,通过服务容器获取: + +```typescript +import { Core, WorldManager } from '@esengine/ecs-framework'; + +// 初始化 Core +Core.create({ debug: true }); + +// 从服务容器获取 WorldManager(Core 已自动创建并注册) +const worldManager = Core.services.resolve(WorldManager); +``` + +### 创建 World + +```typescript +// 创建游戏房间 World +const room1 = worldManager.createWorld('room_001', { + name: 'GameRoom_001', + maxScenes: 5, + debug: true +}); + +// 激活 World +worldManager.setWorldActive('room_001', true); + +// 创建更多房间 +const room2 = worldManager.createWorld('room_002', { + name: 'GameRoom_002', + maxScenes: 5 +}); + +worldManager.setWorldActive('room_002', true); +``` + +### 游戏循环 + +在游戏循环中更新所有活跃的 World: + +```typescript +function gameLoop(deltaTime: number) { + Core.update(deltaTime); // 更新全局服务 + worldManager.updateAll(); // 更新所有活跃的 World +} + +// 启动游戏循环 +let lastTime = 0; +setInterval(() => { + const currentTime = Date.now(); + const deltaTime = (currentTime - lastTime) / 1000; + lastTime = currentTime; + + gameLoop(deltaTime); +}, 16); // 60 FPS +``` + +## World 管理 + +### 创建 World + +```typescript +// 基本创建 +const world = worldManager.createWorld('worldId'); + +// 带配置创建 +const world = worldManager.createWorld('worldId', { + name: 'MyWorld', + maxScenes: 10, + autoCleanup: true, + debug: true +}); +``` + +**配置选项(IWorldConfig)**: +- `name?: string` - World 名称 +- `maxScenes?: number` - 最大场景数量限制(默认 10) +- `autoCleanup?: boolean` - 是否自动清理空场景(默认 true) +- `debug?: boolean` - 是否启用调试模式(默认 false) + +### 获取 World + +```typescript +// 通过 ID 获取 +const world = worldManager.getWorld('room_001'); +if (world) { + console.log(`World: ${world.name}`); +} + +// 获取所有 World +const allWorlds = worldManager.getAllWorlds(); +console.log(`共有 ${allWorlds.length} 个 World`); + +// 获取所有 World ID +const worldIds = worldManager.getWorldIds(); +console.log('World 列表:', worldIds); + +// 通过名称查找 +const world = worldManager.findWorldByName('GameRoom_001'); +``` + +### 激活和停用 World + +```typescript +// 激活 World(开始运行和更新) +worldManager.setWorldActive('room_001', true); + +// 停用 World(停止更新但保留数据) +worldManager.setWorldActive('room_001', false); + +// 检查 World 是否激活 +if (worldManager.isWorldActive('room_001')) { + console.log('房间正在运行'); +} + +// 获取所有活跃的 World +const activeWorlds = worldManager.getActiveWorlds(); +console.log(`当前有 ${activeWorlds.length} 个活跃 World`); +``` + +### 移除 World + +```typescript +// 移除 World(会自动停用并销毁) +const removed = worldManager.removeWorld('room_001'); +if (removed) { + console.log('World 已移除'); +} +``` + +## World 中的场景管理 + +每个 World 可以包含多个 Scene 并独立管理它们的生命周期。 + +### 创建场景 + +```typescript +const world = worldManager.getWorld('room_001'); +if (!world) return; + +// 创建场景 +const mainScene = world.createScene('main', new MainScene()); +const uiScene = world.createScene('ui', new UIScene()); +const hudScene = world.createScene('hud', new HUDScene()); + +// 激活场景 +world.setSceneActive('main', true); +world.setSceneActive('ui', true); +world.setSceneActive('hud', false); +``` + +### 查询场景 + +```typescript +// 获取特定场景 +const mainScene = world.getScene('main'); +if (mainScene) { + console.log(`场景名称: ${mainScene.name}`); +} + +// 获取所有场景 +const allScenes = world.getAllScenes(); +console.log(`World 中共有 ${allScenes.length} 个场景`); + +// 获取所有场景 ID +const sceneIds = world.getSceneIds(); +console.log('场景列表:', sceneIds); + +// 获取活跃场景数量 +const activeCount = world.getActiveSceneCount(); +console.log(`当前有 ${activeCount} 个活跃场景`); + +// 检查场景是否激活 +if (world.isSceneActive('main')) { + console.log('主场景正在运行'); +} +``` + +### 场景切换 + +World 支持多场景同时运行,也支持场景切换: + +```typescript +class GameWorld { + private world: World; + + constructor(worldManager: WorldManager) { + this.world = worldManager.createWorld('game', { + name: 'GameWorld', + maxScenes: 5 + }); + + // 创建所有场景 + this.world.createScene('menu', new MenuScene()); + this.world.createScene('game', new GameScene()); + this.world.createScene('pause', new PauseScene()); + this.world.createScene('gameover', new GameOverScene()); + + // 激活 World + worldManager.setWorldActive('game', true); + } + + public showMenu(): void { + this.deactivateAllScenes(); + this.world.setSceneActive('menu', true); + } + + public startGame(): void { + this.deactivateAllScenes(); + this.world.setSceneActive('game', true); + } + + public pauseGame(): void { + // 游戏场景继续存在但停止更新 + this.world.setSceneActive('game', false); + // 显示暂停界面 + this.world.setSceneActive('pause', true); + } + + public resumeGame(): void { + this.world.setSceneActive('pause', false); + this.world.setSceneActive('game', true); + } + + public showGameOver(): void { + this.deactivateAllScenes(); + this.world.setSceneActive('gameover', true); + } + + private deactivateAllScenes(): void { + const sceneIds = this.world.getSceneIds(); + sceneIds.forEach(id => this.world.setSceneActive(id, false)); + } +} +``` + +### 移除场景 + +```typescript +// 移除不再需要的场景 +const removed = world.removeScene('oldScene'); +if (removed) { + console.log('场景已移除'); +} + +// 场景会自动调用 end() 方法进行清理 +``` + +## 全局系统 + +World 支持全局系统,这些系统在 World 级别运行,不依赖特定 Scene。 + +### 定义全局系统 + +```typescript +import { IGlobalSystem } from '@esengine/ecs-framework'; + +// 网络系统(World 级别) +class NetworkSystem implements IGlobalSystem { + readonly name = 'NetworkSystem'; + + private connectionId: string; + + constructor(connectionId: string) { + this.connectionId = connectionId; + } + + initialize(): void { + console.log(`网络系统初始化: ${this.connectionId}`); + // 建立网络连接 + } + + update(deltaTime?: number): void { + // 处理网络消息,不依赖任何 Scene + // 接收和发送网络包 + } + + destroy(): void { + console.log(`网络系统销毁: ${this.connectionId}`); + // 关闭网络连接 + } +} + +// 物理系统(World 级别) +class PhysicsSystem implements IGlobalSystem { + readonly name = 'PhysicsSystem'; + + initialize(): void { + console.log('物理系统初始化'); + } + + update(deltaTime?: number): void { + // 物理模拟,作用于 World 中所有场景 + } + + destroy(): void { + console.log('物理系统销毁'); + } +} +``` + +### 使用全局系统 + +```typescript +const world = worldManager.getWorld('room_001'); +if (!world) return; + +// 添加全局系统 +const networkSystem = world.addGlobalSystem(new NetworkSystem('conn_001')); +const physicsSystem = world.addGlobalSystem(new PhysicsSystem()); + +// 获取全局系统 +const network = world.getGlobalSystem(NetworkSystem); +if (network) { + console.log('找到网络系统'); +} + +// 移除全局系统 +world.removeGlobalSystem(networkSystem); +``` + +## 批量操作 + +### 更新所有 World + +```typescript +// 更新所有活跃的 World(应该在游戏循环中调用) +worldManager.updateAll(); + +// 这会自动更新每个 World 的: +// 1. 全局系统 +// 2. 所有活跃场景 +``` + +### 启动和停止 + +```typescript +// 启动所有 World +worldManager.startAll(); + +// 停止所有 World +worldManager.stopAll(); + +// 检查是否正在运行 +if (worldManager.isRunning) { + console.log('WorldManager 正在运行'); +} +``` + +### 查找 World + +```typescript +// 使用条件查找 +const emptyWorlds = worldManager.findWorlds(world => { + return world.sceneCount === 0; +}); + +// 查找活跃的 World +const activeWorlds = worldManager.findWorlds(world => { + return world.isActive; +}); + +// 查找特定名称的 World +const world = worldManager.findWorldByName('GameRoom_001'); +``` + +## 统计和监控 + +### 获取统计信息 + +```typescript +const stats = worldManager.getStats(); + +console.log(`总 World 数: ${stats.totalWorlds}`); +console.log(`活跃 World 数: ${stats.activeWorlds}`); +console.log(`总场景数: ${stats.totalScenes}`); +console.log(`总实体数: ${stats.totalEntities}`); +console.log(`总系统数: ${stats.totalSystems}`); + +// 查看每个 World 的详细信息 +stats.worlds.forEach(worldInfo => { + console.log(`World: ${worldInfo.name}`); + console.log(` 场景数: ${worldInfo.sceneCount}`); + console.log(` 是否活跃: ${worldInfo.isActive}`); +}); +``` + +### 获取详细状态 + +```typescript +const status = worldManager.getDetailedStatus(); + +// 包含所有 World 的详细状态 +status.worlds.forEach(worldStatus => { + console.log(`World ID: ${worldStatus.id}`); + console.log(`状态:`, worldStatus.status); +}); +``` + +## 自动清理 + +WorldManager 支持自动清理空的 World。 + +### 配置清理 + +```typescript +// 创建带清理配置的 WorldManager +const worldManager = Core.services.resolve(WorldManager); + +// WorldManager 的配置在 Core 中设置: +// { +// maxWorlds: 50, +// autoCleanup: true, +// cleanupInterval: 30000 // 30 秒 +// } +``` + +### 手动清理 + +```typescript +// 手动触发清理 +const cleanedCount = worldManager.cleanup(); +console.log(`清理了 ${cleanedCount} 个 World`); +``` + +**清理条件**: +- World 未激活 +- 没有 Scene 或所有 Scene 都是空的 +- 创建时间超过 10 分钟 + +## API 参考 + +### WorldManager API + +| 方法 | 说明 | +|------|------| +| `createWorld(worldId, config?)` | 创建新 World | +| `removeWorld(worldId)` | 移除 World | +| `getWorld(worldId)` | 获取 World | +| `getAllWorlds()` | 获取所有 World | +| `getWorldIds()` | 获取所有 World ID | +| `setWorldActive(worldId, active)` | 设置 World 激活状态 | +| `isWorldActive(worldId)` | 检查 World 是否激活 | +| `getActiveWorlds()` | 获取所有活跃的 World | +| `updateAll()` | 更新所有活跃 World | +| `startAll()` | 启动所有 World | +| `stopAll()` | 停止所有 World | +| `findWorlds(predicate)` | 查找满足条件的 World | +| `findWorldByName(name)` | 根据名称查找 World | +| `getStats()` | 获取统计信息 | +| `getDetailedStatus()` | 获取详细状态信息 | +| `cleanup()` | 清理空 World | +| `destroy()` | 销毁 WorldManager | + +### World API + +| 方法 | 说明 | +|------|------| +| `createScene(sceneId, sceneInstance?)` | 创建并添加 Scene | +| `removeScene(sceneId)` | 移除 Scene | +| `getScene(sceneId)` | 获取 Scene | +| `getAllScenes()` | 获取所有 Scene | +| `getSceneIds()` | 获取所有 Scene ID | +| `setSceneActive(sceneId, active)` | 设置 Scene 激活状态 | +| `isSceneActive(sceneId)` | 检查 Scene 是否激活 | +| `getActiveSceneCount()` | 获取活跃 Scene 数量 | +| `addGlobalSystem(system)` | 添加全局系统 | +| `removeGlobalSystem(system)` | 移除全局系统 | +| `getGlobalSystem(type)` | 获取全局系统 | +| `start()` | 启动 World | +| `stop()` | 停止 World | +| `updateGlobalSystems()` | 更新全局系统 | +| `updateScenes()` | 更新所有激活 Scene | +| `destroy()` | 销毁 World | +| `getStatus()` | 获取 World 状态 | +| `getStats()` | 获取统计信息 | + +### 属性 + +| 属性 | 说明 | +|------|------| +| `worldCount` | World 总数 | +| `activeWorldCount` | 活跃 World 数量 | +| `isRunning` | 是否正在运行 | +| `config` | 配置信息 | + +## 完整示例 + +### MMO 游戏房间系统 + +```typescript +import { Core, WorldManager, Scene, World } from '@esengine/ecs-framework'; + +// 初始化 +Core.create({ debug: true }); +const worldManager = Core.services.resolve(WorldManager); + +// 房间管理器 +class RoomManager { + private worldManager: WorldManager; + private rooms: Map = new Map(); + + constructor(worldManager: WorldManager) { + this.worldManager = worldManager; + } + + // 创建游戏房间 + public createRoom(roomId: string, maxPlayers: number): World { + const world = this.worldManager.createWorld(roomId, { + name: `Room_${roomId}`, + maxScenes: 3, + debug: true + }); + + // 创建房间场景 + world.createScene('lobby', new LobbyScene()); + world.createScene('game', new GameScene()); + world.createScene('result', new ResultScene()); + + // 添加房间级别的系统 + world.addGlobalSystem(new NetworkSystem(roomId)); + world.addGlobalSystem(new RoomLogicSystem(maxPlayers)); + + // 激活 World 和初始场景 + this.worldManager.setWorldActive(roomId, true); + world.setSceneActive('lobby', true); + + this.rooms.set(roomId, world); + console.log(`房间 ${roomId} 已创建`); + + return world; + } + + // 玩家加入房间 + public joinRoom(roomId: string, playerId: string): boolean { + const world = this.rooms.get(roomId); + if (!world) { + console.log(`房间 ${roomId} 不存在`); + return false; + } + + // 在大厅场景中创建玩家实体 + const lobbyScene = world.getScene('lobby'); + if (lobbyScene) { + const player = lobbyScene.createEntity(`Player_${playerId}`); + // 添加玩家组件... + console.log(`玩家 ${playerId} 加入房间 ${roomId}`); + return true; + } + + return false; + } + + // 开始游戏 + public startGame(roomId: string): void { + const world = this.rooms.get(roomId); + if (!world) return; + + // 切换到游戏场景 + world.setSceneActive('lobby', false); + world.setSceneActive('game', true); + + console.log(`房间 ${roomId} 游戏开始`); + } + + // 结束游戏 + public endGame(roomId: string): void { + const world = this.rooms.get(roomId); + if (!world) return; + + // 切换到结果场景 + world.setSceneActive('game', false); + world.setSceneActive('result', true); + + console.log(`房间 ${roomId} 游戏结束`); + } + + // 关闭房间 + public closeRoom(roomId: string): void { + this.worldManager.removeWorld(roomId); + this.rooms.delete(roomId); + console.log(`房间 ${roomId} 已关闭`); + } + + // 获取房间列表 + public getRoomList(): string[] { + return Array.from(this.rooms.keys()); + } + + // 获取房间统计 + public getRoomStats(roomId: string) { + const world = this.rooms.get(roomId); + return world?.getStats(); + } +} + +// 使用房间管理器 +const roomManager = new RoomManager(worldManager); + +// 创建多个游戏房间 +roomManager.createRoom('room_001', 4); +roomManager.createRoom('room_002', 4); +roomManager.createRoom('room_003', 2); + +// 玩家加入 +roomManager.joinRoom('room_001', 'player_1'); +roomManager.joinRoom('room_001', 'player_2'); + +// 开始游戏 +roomManager.startGame('room_001'); + +// 游戏循环 +function gameLoop(deltaTime: number) { + Core.update(deltaTime); + worldManager.updateAll(); // 更新所有房间 +} + +// 定期清理空房间 +setInterval(() => { + const stats = worldManager.getStats(); + console.log(`当前房间数: ${stats.totalWorlds}`); + console.log(`活跃房间数: ${stats.activeWorlds}`); + + worldManager.cleanup(); +}, 60000); // 每分钟清理一次 +``` + +## 最佳实践 + +### 1. 合理的 World 粒度 + +```typescript +// 推荐:每个独立环境一个 World +const room1 = worldManager.createWorld('room_1'); // 游戏房间1 +const room2 = worldManager.createWorld('room_2'); // 游戏房间2 + +// 不推荐:过度使用 World +const world1 = worldManager.createWorld('ui'); // UI 不需要独立 World +const world2 = worldManager.createWorld('menu'); // 菜单不需要独立 World +``` + +### 2. 使用全局系统处理跨场景逻辑 + +```typescript +// 推荐:World 级别的系统 +class NetworkSystem implements IGlobalSystem { + update() { + // 网络处理不依赖场景 + } +} + +// 不推荐:在每个场景中重复创建 +class GameScene extends Scene { + initialize() { + this.addSystem(new NetworkSystem()); // 不应该在场景级别 + } +} +``` + +### 3. 及时清理不用的 World + +```typescript +// 推荐:玩家离开时清理房间 +function onPlayerLeave(roomId: string) { + const world = worldManager.getWorld(roomId); + if (world && world.sceneCount === 0) { + worldManager.removeWorld(roomId); + } +} + +// 或使用自动清理 +worldManager.cleanup(); +``` + +### 4. 监控资源使用 + +```typescript +// 定期检查资源使用情况 +setInterval(() => { + const stats = worldManager.getStats(); + + if (stats.totalWorlds > 100) { + console.warn('World 数量过多,考虑清理'); + worldManager.cleanup(); + } + + if (stats.totalEntities > 10000) { + console.warn('实体数量过多,检查是否有泄漏'); + } +}, 30000); +``` + +## 与 SceneManager 的对比 + +| 特性 | SceneManager | WorldManager | +|------|--------------|--------------| +| 适用场景 | 95% 的游戏应用 | 高级多世界隔离场景 | +| 复杂度 | 简单 | 复杂 | +| 场景数量 | 单场景(可切换) | 多 World,每个 World 多场景 | +| 场景隔离 | 无(场景切换) | 完全隔离(每个 World 独立) | +| 性能开销 | 最小 | 较高 | +| 全局系统 | 无 | 支持(World 级别) | +| 使用示例 | 单人游戏、移动游戏 | MMO 服务器、游戏房间系统 | + +**何时使用 WorldManager**: +- MMO 游戏服务器(每个房间一个 World) +- 游戏大厅系统(每个游戏房间完全隔离) +- 需要运行多个完全独立的游戏实例 +- 服务器端模拟多个游戏世界 + +**何时使用 SceneManager**: +- 单人游戏 +- 简单的多人游戏 +- 移动游戏 +- 场景之间需要切换但不需要同时运行 + +## 架构层次 + +WorldManager 在 ECS Framework 中的位置: + +``` +Core (全局服务) + └── WorldManager (世界管理) + ├── World 1 (游戏房间1) + │ ├── GlobalSystem (全局系统) + │ ├── Scene 1 (场景1) + │ │ ├── EntitySystem + │ │ ├── Entity + │ │ └── Component + │ └── Scene 2 (场景2) + ├── World 2 (游戏房间2) + │ ├── GlobalSystem + │ └── Scene 1 + └── World 3 (游戏房间3) +``` + +WorldManager 为需要多世界隔离的高级应用提供了强大的管理能力。如果你的应用不需要多世界隔离,建议使用更简单的 [SceneManager](./scene-manager.md)。