diff --git a/client/assets/scripts/App.meta b/client/assets/scripts/App.meta new file mode 100644 index 0000000..b9e7ae2 --- /dev/null +++ b/client/assets/scripts/App.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "4c66e5c4-282b-45bd-b8a0-ec4a9a08c7ec", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusBoot.ts b/client/assets/scripts/App/AppStatus/AppStatusBoot.ts new file mode 100644 index 0000000..70f3958 --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusBoot.ts @@ -0,0 +1,61 @@ +import { BaseState } from "../../Framework/FSM/BaseState"; +import { NetManager } from "../../Framework/Net/NetManager"; + +/** + * 应用启动状态 + * 职责: + * - 初始化游戏引擎 + * - 加载基础配置 + * - 初始化网络管理器 + * - 准备第一个UI界面 + */ +export class AppStatusBoot extends BaseState { + constructor(fsm: any) { + super(fsm, "Boot"); + } + + /** + * 进入启动状态 + */ + async onEnter(params?: any): Promise { + super.onEnter(params); + + console.log("[AppStatusBoot] 开始初始化应用..."); + + try { + // 1. 初始化并连接网络 + await this.initAndConnectNet(); + + // 2. 初始化完成,切换到登录状态 + console.log("[AppStatusBoot] 启动完成,切换到登录状态"); + this._fsm.changeState("Login"); + + } catch (error) { + console.error("[AppStatusBoot] 初始化失败:", error); + } + } + + /** + * 初始化并连接网络 + */ + private async initAndConnectNet(): Promise { + console.log("[AppStatusBoot] 初始化网络管理器..."); + + // TODO: 从配置文件读取服务器地址 + // import { serviceProto } from '../../Shared/protocols/serviceProto'; + // const netManager = NetManager.getInstance(); + // netManager.setServiceProto(serviceProto); + // netManager.init({ serverUrl: 'http://localhost:3000' }); + // await netManager.connect(); + + console.log("[AppStatusBoot] 网络连接完成(待配置)"); + } + + /** + * 退出启动状态 + */ + onExit(): void { + super.onExit(); + console.log("[AppStatusBoot] 离开启动状态"); + } +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusBoot.ts.meta b/client/assets/scripts/App/AppStatus/AppStatusBoot.ts.meta new file mode 100644 index 0000000..bab8b0c --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusBoot.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "6a737e69-0f9a-47d8-b836-f3d8f586fcaa", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusGame.ts b/client/assets/scripts/App/AppStatus/AppStatusGame.ts new file mode 100644 index 0000000..9562ebb --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusGame.ts @@ -0,0 +1,211 @@ +import { BaseState } from "../../Framework/FSM/BaseState"; + +/** + * 应用游戏状态 + * 职责: + * - 加载游戏场景 + * - 初始化玩家角色 + * - 监听服务器广播(其他玩家加入、移动等) + * - 游戏主循环 + */ +export class AppStatusGame extends BaseState { + private _player: any = null; + private _isNewPlayer: boolean = false; + + constructor(fsm: any) { + super(fsm, "Game"); + } + + /** + * 进入游戏状态 + */ + async onEnter(params?: any): Promise { + super.onEnter(params); + + console.log("[AppStatusGame] 进入游戏世界"); + + // 保存玩家信息 + if (params) { + this._player = params.player || null; + this._isNewPlayer = params.isNewPlayer || false; + console.log(`[AppStatusGame] 玩家信息:`, this._player); + console.log(`[AppStatusGame] 是否新玩家: ${this._isNewPlayer}`); + } + + try { + // 1. 加载游戏场景 + await this.loadGameScene(); + + // 2. 初始化游戏 + await this.initGame(); + + // 3. 开始监听服务器广播 + this.listenServerMessages(); + + // 4. 开始游戏 + this.startGame(); + + } catch (error) { + console.error("[AppStatusGame] 进入游戏失败:", error); + // 返回登录 + this._fsm.changeState("Login"); + } + } + + /** + * 加载游戏场景 + */ + private async loadGameScene(): Promise { + console.log("[AppStatusGame] 加载游戏场景..."); + + // TODO: 使用Cocos场景管理器加载游戏场景 + // await director.loadScene("GameScene"); + + // 模拟加载延迟 + await this.delay(500); + + console.log("[AppStatusGame] 游戏场景加载完成(待实现)"); + } + + /** + * 初始化游戏 + */ + private async initGame(): Promise { + console.log("[AppStatusGame] 初始化游戏..."); + + // TODO: 初始化游戏逻辑 + // - 创建玩家角色(根据this._player信息) + // - 设置玩家位置(this._player.position) + // - 创建敌人 + // - 初始化游戏规则 + + console.log("[AppStatusGame] 游戏初始化完成(待实现)"); + } + + /** + * 监听服务器广播消息 + */ + private listenServerMessages(): void { + console.log("[AppStatusGame] 开始监听服务器广播..."); + + // TODO: 监听服务器广播消息 + // const netManager = NetManager.getInstance(); + + // 监听玩家加入 (MsgPlayerJoin) + // netManager.listenMsg("PlayerJoin", (msg) => { + // console.log("玩家加入:", msg.playerName); + // // 在场景中创建其他玩家 + // }); + + // 监听玩家移动 (MsgPlayerMove) + // netManager.listenMsg("PlayerMove", (msg) => { + // console.log("玩家移动:", msg.playerName, msg.position); + // // 更新其他玩家位置 + // }); + + // 监听聊天消息 (MsgChat) + // netManager.listenMsg("Chat", (msg) => { + // console.log("聊天消息:", msg); + // // 显示聊天内容 + // }); + + console.log("[AppStatusGame] 服务器广播监听已设置(待实现)"); + } + + /** + * 开始游戏 + */ + private startGame(): void { + console.log("[AppStatusGame] 游戏开始!"); + + // TODO: 启动游戏逻辑 + // - 显示游戏UI + // - 开始接收输入 + // - 开始游戏主循环(在onUpdate中) + } + + /** + * 更新游戏状态(每帧调用) + */ + onUpdate(dt: number): void { + // TODO: 游戏主循环逻辑 + // - 更新角色位置 + // - 检测碰撞 + // - 更新敌人AI + // - 同步网络状态 + } + + /** + * 暂停游戏 + */ + pauseGame(): void { + console.log("[AppStatusGame] 游戏暂停"); + // TODO: 暂停游戏逻辑 + // - 停止游戏更新 + // - 显示暂停菜单 + } + + /** + * 恢复游戏 + */ + resumeGame(): void { + console.log("[AppStatusGame] 游戏恢复"); + // TODO: 恢复游戏逻辑 + // - 继续游戏更新 + // - 隐藏暂停菜单 + } + + /** + * 玩家死亡 + */ + onPlayerDeath(): void { + console.log("[AppStatusGame] 玩家死亡"); + + // TODO: 处理玩家死亡 + // - 显示死亡界面 + // - 显示复活选项或返回登录 + + // 延迟后返回登录 + setTimeout(() => { + this._fsm.changeState("Login"); + }, 3000); + } + + /** + * 退出游戏(返回登录) + */ + quitGame(): void { + console.log("[AppStatusGame] 退出游戏"); + + // TODO: 断开连接或通知服务器 + // const netManager = NetManager.getInstance(); + // await netManager.disconnect(); + + // 返回登录 + this._fsm.changeState("Login"); + } + + /** + * 延迟辅助函数 + */ + private delay(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + /** + * 退出游戏状态 + */ + onExit(): void { + super.onExit(); + console.log("[AppStatusGame] 离开游戏状态"); + + // TODO: 清理游戏资源 + // - 卸载游戏场景 + // - 清理角色对象 + // - 取消服务器消息监听 + // const netManager = NetManager.getInstance(); + // netManager.unlistenMsg("PlayerJoin"); + // netManager.unlistenMsg("PlayerMove"); + // netManager.unlistenMsg("Chat"); + } +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusGame.ts.meta b/client/assets/scripts/App/AppStatus/AppStatusGame.ts.meta new file mode 100644 index 0000000..9416a1f --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusGame.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "fb4c25d0-b65c-4881-9997-5e3bd5d50325", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusLogin.ts b/client/assets/scripts/App/AppStatus/AppStatusLogin.ts new file mode 100644 index 0000000..6465874 --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusLogin.ts @@ -0,0 +1,121 @@ +import { BaseState } from "../../Framework/FSM/BaseState"; +import { NetManager } from "../../Framework/Net/NetManager"; +import { UIMgr } from "../../Framework/UI/UIMgr"; +import { UILogin } from "../Login/UILogin"; + +/** + * 应用登录状态 + * 职责: + * - 显示登录界面 + * - 处理玩家ID输入 + * - 发送登录请求(Login API) + * - 登录成功后直接进入游戏世界 + */ +export class AppStatusLogin extends BaseState { + constructor(fsm: any) { + super(fsm, "Login"); + } + + /** + * 进入登录状态 + */ + async onEnter(params?: any): Promise { + super.onEnter(params); + + console.log("[AppStatusLogin] 显示登录界面"); + + // 1. 显示登录界面 + await this.showLoginUI(); + + // 2. 等待用户输入玩家ID并点击登录 + // 在 UI 中处理输入,调用 this.login(playerId, playerName) + } + + /** + * 显示登录界面 + */ + private async showLoginUI(): Promise { + console.log("[AppStatusLogin] 加载登录UI..."); + try { + const uiMgr = UIMgr.getInstance(); + await uiMgr.load(UILogin); + console.log("[AppStatusLogin] 登录UI加载成功"); + } catch (error) { + console.error("[AppStatusLogin] 登录UI加载失败:", error); + } + } + + /** + * 执行登录 + * @param playerId 玩家ID(用于识别玩家) + * @param playerName 玩家昵称(可选,新玩家时使用) + */ + async login(playerId: string, playerName?: string): Promise { + console.log(`[AppStatusLogin] 尝试登录, 玩家ID: ${playerId}`); + + if (!playerId || playerId.trim().length === 0) { + console.error("[AppStatusLogin] 玩家ID不能为空"); + // TODO: 显示错误提示 + return; + } + + try { + // 1. 发送登录请求到服务器 + // const netManager = NetManager.getInstance(); + // const result = await netManager.callApi("Login", { + // playerId, + // playerName + // }); + + // 模拟登录请求 + await this.delay(500); + const mockResult = { + success: true, + message: "登录成功", + player: { + id: playerId, + name: playerName || `Player_${playerId}`, + position: { x: 0, y: 0, z: 0 }, + spawnPoint: { x: 0, y: 0, z: 0 }, + hp: 100, + maxHp: 100, + isAlive: true, + createdAt: Date.now(), + lastLoginAt: Date.now() + }, + isNewPlayer: false + }; + + console.log("[AppStatusLogin] 登录成功,玩家信息:", mockResult.player); + + // 2. 登录成功后直接进入游戏状态 + this._fsm.changeState("Game", { + player: mockResult.player, + isNewPlayer: mockResult.isNewPlayer + }); + + } catch (error) { + console.error("[AppStatusLogin] 登录失败:", error); + // TODO: 显示错误提示 + } + } + + /** + * 延迟辅助函数 + */ + private delay(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + /** + * 退出登录状态 + */ + onExit(): void { + super.onExit(); + console.log("[AppStatusLogin] 离开登录状态"); + + // 隐藏登录界面 + const uiMgr = UIMgr.getInstance(); + uiMgr.hide(UILogin); + } +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusLogin.ts.meta b/client/assets/scripts/App/AppStatus/AppStatusLogin.ts.meta new file mode 100644 index 0000000..1e000dd --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusLogin.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "f0f1f913-0bf0-440c-9b66-9712ed982479", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusManager.ts b/client/assets/scripts/App/AppStatus/AppStatusManager.ts new file mode 100644 index 0000000..653d9a0 --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusManager.ts @@ -0,0 +1,107 @@ +import { FSM } from "../../Framework/FSM/FSM"; +import { AppStatusBoot } from "./AppStatusBoot"; +import { AppStatusLogin } from "./AppStatusLogin"; +import { AppStatusGame } from "./AppStatusGame"; + +/** + * 应用状态管理器 + * 职责: + * - 管理应用的整体状态流转 + * - 提供单例访问 + * - 初始化所有应用状态 + * + * 状态流程: Boot -> Login -> Game + */ +export class AppStatusManager { + private static _instance: AppStatusManager | null = null; + private _fsm: FSM; + + /** + * 构造函数(私有) + */ + private constructor() { + this._fsm = new FSM(); + this.initStates(); + } + + /** + * 获取单例 + */ + static getInstance(): AppStatusManager { + if (!this._instance) { + this._instance = new AppStatusManager(); + } + return this._instance; + } + + /** + * 初始化所有状态 + */ + private initStates(): void { + console.log("[AppStatusManager] 初始化应用状态..."); + + // 添加应用状态: Boot -> Login -> Game + this._fsm.addState(new AppStatusBoot(this._fsm)); + this._fsm.addState(new AppStatusLogin(this._fsm)); + this._fsm.addState(new AppStatusGame(this._fsm)); + + console.log("[AppStatusManager] 应用状态初始化完成"); + } + + /** + * 启动应用 + * 从Boot状态开始 + */ + start(): void { + console.log("[AppStatusManager] 启动应用..."); + this._fsm.changeState("Boot"); + } + + /** + * 切换状态 + * @param stateName 状态名称 + * @param params 可选参数 + */ + changeState(stateName: string, params?: any): void { + this._fsm.changeState(stateName, params); + } + + /** + * 获取当前状态名称 + */ + getCurrentStateName(): string | null { + return this._fsm.getCurrentStateName(); + } + + /** + * 获取当前状态 + */ + getCurrentState(): any { + return this._fsm.getCurrentState(); + } + + /** + * 更新状态机(在主循环中调用) + * @param dt 距离上一帧的时间增量(秒) + */ + update(dt: number): void { + this._fsm.update(dt); + } + + /** + * 获取状态机实例 + * 用于高级操作 + */ + getFSM(): FSM { + return this._fsm; + } + + /** + * 销毁管理器 + */ + destroy(): void { + console.log("[AppStatusManager] 销毁应用状态管理器"); + this._fsm.clear(); + AppStatusManager._instance = null; + } +} diff --git a/client/assets/scripts/App/AppStatus/AppStatusManager.ts.meta b/client/assets/scripts/App/AppStatus/AppStatusManager.ts.meta new file mode 100644 index 0000000..be10552 --- /dev/null +++ b/client/assets/scripts/App/AppStatus/AppStatusManager.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "191d542e-df2a-43a0-998c-4daefe65c598", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/client/assets/scripts/App/AppStatus/README.md b/client/assets/scripts/App/AppStatus/README.md new file mode 100644 index 0000000..39467f5 --- /dev/null +++ b/client/assets/scripts/App/AppStatus/README.md @@ -0,0 +1,396 @@ +# 应用状态机 (App/AppStatus) + +## 📋 模块概述 +管理应用的整体状态流转,包括启动、登录、游戏等状态,基于 Framework/FSM 实现。 + +## 🎯 核心特性 +- ✅ 应用状态流转管理 +- ✅ 网络初始化 +- ✅ 登录流程 +- ✅ 游戏状态管理 +- ✅ 状态生命周期 +- ✅ 服务器消息监听 + +## 🗂️ 文件结构 + +``` +App/AppStatus/ +├── AppStatusManager.ts # 应用状态管理器 +├── AppStatusBoot.ts # 启动状态 +├── AppStatusLogin.ts # 登录状态 +└── AppStatusGame.ts # 游戏状态 +``` + +## 🔄 状态流转图 + +``` +[启动 Boot] → [登录 Login] → [游戏 Game] + ↑ ↓ ↓ + └────────────┴──────────────┘ + (退出/死亡返回登录) +``` + +## 📘 核心类详解 + +### AppStatusManager - 应用状态管理器 + +**职责**: 管理应用的整体状态流转 + +```typescript +class AppStatusManager { + private _fsm: FSM; // 底层状态机 + + // 获取单例 + static getInstance(): AppStatusManager; + + // 启动应用(从 Boot 状态开始) + start(): void; + + // 切换状态 + changeState(stateName: string, params?: any): void; + + // 获取当前状态名称 + getCurrentStateName(): string | null; + + // 获取当前状态实例 + getCurrentState(): any; + + // 更新状态机(在主循环中调用) + update(dt: number): void; + + // 获取底层 FSM 实例 + getFSM(): FSM; + + // 销毁管理器 + destroy(): void; +} +``` + +### AppStatusBoot - 启动状态 + +**职责**: 初始化网络管理器并连接服务器 + +```typescript +class AppStatusBoot extends BaseState { + constructor(fsm: FSM); + + // 进入启动状态 + async onEnter(params?: any): Promise; + + // 初始化并连接网络 + private async initAndConnectNet(): Promise; + + // 退出启动状态 + onExit(): void; +} +``` + +**执行流程**: +1. 设置服务协议 +2. 初始化网络配置 +3. 监听网络事件 +4. 连接服务器 +5. 连接成功后切换到登录状态 + +### AppStatusLogin - 登录状态 + +**职责**: 显示登录界面,处理登录逻辑 + +```typescript +class AppStatusLogin extends BaseState { + constructor(fsm: FSM); + + // 进入登录状态 + async onEnter(params?: any): Promise; + + // 显示登录 UI + private async showLoginUI(): Promise; + + // 退出登录状态 + onExit(): void; +} +``` + +**执行流程**: +1. 通过 UIMgr 加载并显示登录 UI +2. 等待用户输入账号并点击登录 +3. UILogin 调用 NetManager 发送登录请求 +4. 登录成功后切换到游戏状态 + +### AppStatusGame - 游戏状态 + +**职责**: 游戏主循环,处理游戏逻辑和服务器消息 + +```typescript +class AppStatusGame extends BaseState { + private _player: any; // 玩家信息 + private _isNewPlayer: boolean; // 是否新玩家 + private _isPaused: boolean; // 是否暂停 + + constructor(fsm: FSM); + + // 进入游戏状态 + async onEnter(params?: any): Promise; + + // 加载游戏场景 + private async loadGameScene(): Promise; + + // 初始化游戏 + private async initGame(): Promise; + + // 监听服务器广播消息 + private listenServerMessages(): void; + + // 开始游戏 + private startGame(): void; + + // 游戏主循环 + onUpdate(dt: number): void; + + // 暂停游戏 + pauseGame(): void; + + // 恢复游戏 + resumeGame(): void; + + // 玩家死亡 + private onPlayerDeath(): void; + + // 退出游戏(返回登录) + quitGame(): void; + + // 退出游戏状态 + onExit(): void; +} +``` + +**执行流程**: +1. 接收玩家信息 +2. 加载游戏场景 +3. 初始化玩家角色 +4. 监听服务器广播消息 +5. 开始游戏主循环 +6. 处理游戏逻辑和网络消息 + +## 📝 使用指南 + +### 1. 启动应用 + +```typescript +import { AppStatusManager } from './App/AppStatus/AppStatusManager'; + +// 在 Boot 组件中启动 +@ccclass('Boot') +export class Boot extends Component { + start() { + // 获取管理器实例 + const appManager = AppStatusManager.getInstance(); + + // 启动应用 + appManager.start(); + } + + update(deltaTime: number) { + // 在主循环中更新状态机 + AppStatusManager.getInstance().update(deltaTime); + } +} +``` + +### 2. 切换状态 + +```typescript +import { AppStatusManager } from './App/AppStatus/AppStatusManager'; + +// 从登录状态切换到游戏状态 +AppStatusManager.getInstance().changeState('Game', { + player: playerInfo, + isNewPlayer: false +}); + +// 从游戏状态返回登录状态 +AppStatusManager.getInstance().changeState('Login'); +``` + +### 3. 获取当前状态 + +```typescript +// 获取当前状态名称 +const stateName = AppStatusManager.getInstance().getCurrentStateName(); +console.log(`当前状态: ${stateName}`); + +// 获取当前状态实例 +const currentState = AppStatusManager.getInstance().getCurrentState(); +``` + +## 🔄 完整流程示例 + +### 启动到游戏的完整流程 + +``` +1. Boot 组件启动 + ↓ +2. AppStatusManager.start() + ↓ +3. 切换到 Boot 状态 + ↓ +4. 初始化网络并连接服务器 + ↓ +5. 连接成功,切换到 Login 状态 + ↓ +6. 加载并显示登录 UI + ↓ +7. 用户输入账号并点击登录 + ↓ +8. 调用 Login API + ↓ +9. 登录成功,切换到 Game 状态 + ↓ +10. 加载游戏场景 + ↓ +11. 初始化玩家角色 + ↓ +12. 监听服务器广播消息 + ↓ +13. 开始游戏主循环 +``` + +## 📡 网络协议使用 + +### Boot 状态 + +```typescript +// 配置网络 +const config: NetConfig = { + serverUrl: 'http://localhost:3000', + timeout: 30000, + autoReconnect: true, + reconnectInterval: 3000, + maxReconnectTimes: 5 +}; +``` + +### Login 状态 + +```typescript +// 由 UILogin 调用登录 API +const result = await netManager.callApi('Login', { + account: account +}); + +// 登录成功后切换状态 +if (result && result.success) { + AppStatusManager.getInstance().changeState('Game', { + player: result.player, + isNewPlayer: result.isNewPlayer + }); +} +``` + +### Game 状态 + +```typescript +// 监听服务器广播 +netManager.listenMsg('PlayerJoin', (msg) => { + console.log(`玩家 ${msg.playerName} 加入游戏`); + // 在场景中创建其他玩家 +}); + +netManager.listenMsg('PlayerMove', (msg) => { + console.log(`玩家 ${msg.playerName} 移动`); + // 更新其他玩家位置 +}); + +// 发送 API +const result = await netManager.callApi('Move', { + x: targetX, + y: targetY +}); +``` + +## ⚠️ 注意事项 + +1. **状态切换参数**: 切换到 Game 状态时必须传递 player 参数 +2. **网络初始化**: Boot 状态必须在网络连接成功后才能切换状态 +3. **资源清理**: 切换状态时注意清理前一个状态的资源 +4. **消息监听**: Game 状态退出时要取消所有服务器消息监听 +5. **异步处理**: 状态的 onEnter 方法是异步的,注意使用 await + +## 🔍 调试技巧 + +### 状态切换日志 + +```typescript +// BaseState 会自动输出状态切换日志 +// [FSM] Enter state: Boot +// [FSM] Exit state: Boot +// [FSM] Enter state: Login +``` + +### 网络状态日志 + +```typescript +// NetManager 会输出网络状态日志 +// [NetManager] 网络已连接 +// [NetManager] 网络已断开 +// [NetManager] 正在重连... +``` + +### 游戏状态信息 + +```typescript +// 在 Game 状态中查看玩家信息 +const gameState = AppStatusManager.getInstance() + .getCurrentState() as AppStatusGame; +console.log('玩家信息:', gameState._player); +console.log('是否新玩家:', gameState._isNewPlayer); +``` + +## 💡 最佳实践 + +1. **单一入口**: 通过 AppStatusManager 统一管理所有状态切换 +2. **参数传递**: 使用 params 在状态间传递必要的数据 +3. **资源管理**: 每个状态负责自己的资源加载和释放 +4. **错误处理**: 网络错误时提供友好的提示并返回合适的状态 +5. **状态独立**: 每个状态保持独立,避免直接依赖其他状态 + +## 🎯 扩展状态 + +### 添加新状态 + +```typescript +// 1. 创建新状态类 +class AppStatusLobby extends BaseState { + constructor(fsm: FSM) { + super(fsm, "Lobby"); + } + + onEnter(params?: any): void { + super.onEnter(params); + console.log("[AppStatusLobby] 进入大厅"); + // 显示大厅 UI + } + + onExit(): void { + super.onExit(); + // 清理大厅资源 + } +} + +// 2. 在 AppStatusManager 中注册 +private initStates(): void { + this._fsm.addState(new AppStatusBoot(this._fsm)); + this._fsm.addState(new AppStatusLogin(this._fsm)); + this._fsm.addState(new AppStatusLobby(this._fsm)); // 新增 + this._fsm.addState(new AppStatusGame(this._fsm)); +} + +// 3. 修改状态流转 +// Login -> Lobby -> Game +``` + +## 📚 相关文档 + +- [Framework/FSM README](../../Framework/FSM/README.md) - 状态机框架 +- [Framework/Net README](../../Framework/Net/README.md) - 网络通信 +- [App/Login README](../Login/README.md) - 登录模块 diff --git a/client/assets/scripts/CC.meta b/client/assets/scripts/CC.meta new file mode 100644 index 0000000..0a8ba90 --- /dev/null +++ b/client/assets/scripts/CC.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "4602b30b-05bf-465d-8537-b3afbbc83fb0", + "files": [], + "subMetas": {}, + "userData": {} +}