简单应用状态机
This commit is contained in:
9
client/assets/scripts/App.meta
Normal file
9
client/assets/scripts/App.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "4c66e5c4-282b-45bd-b8a0-ec4a9a08c7ec",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
61
client/assets/scripts/App/AppStatus/AppStatusBoot.ts
Normal file
61
client/assets/scripts/App/AppStatus/AppStatusBoot.ts
Normal file
@@ -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<void> {
|
||||
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<void> {
|
||||
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] 离开启动状态");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "6a737e69-0f9a-47d8-b836-f3d8f586fcaa",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
211
client/assets/scripts/App/AppStatus/AppStatusGame.ts
Normal file
211
client/assets/scripts/App/AppStatus/AppStatusGame.ts
Normal file
@@ -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<void> {
|
||||
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<void> {
|
||||
console.log("[AppStatusGame] 加载游戏场景...");
|
||||
|
||||
// TODO: 使用Cocos场景管理器加载游戏场景
|
||||
// await director.loadScene("GameScene");
|
||||
|
||||
// 模拟加载延迟
|
||||
await this.delay(500);
|
||||
|
||||
console.log("[AppStatusGame] 游戏场景加载完成(待实现)");
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化游戏
|
||||
*/
|
||||
private async initGame(): Promise<void> {
|
||||
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<void> {
|
||||
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");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "fb4c25d0-b65c-4881-9997-5e3bd5d50325",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
121
client/assets/scripts/App/AppStatus/AppStatusLogin.ts
Normal file
121
client/assets/scripts/App/AppStatus/AppStatusLogin.ts
Normal file
@@ -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<void> {
|
||||
super.onEnter(params);
|
||||
|
||||
console.log("[AppStatusLogin] 显示登录界面");
|
||||
|
||||
// 1. 显示登录界面
|
||||
await this.showLoginUI();
|
||||
|
||||
// 2. 等待用户输入玩家ID并点击登录
|
||||
// 在 UI 中处理输入,调用 this.login(playerId, playerName)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示登录界面
|
||||
*/
|
||||
private async showLoginUI(): Promise<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录状态
|
||||
*/
|
||||
onExit(): void {
|
||||
super.onExit();
|
||||
console.log("[AppStatusLogin] 离开登录状态");
|
||||
|
||||
// 隐藏登录界面
|
||||
const uiMgr = UIMgr.getInstance();
|
||||
uiMgr.hide(UILogin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f0f1f913-0bf0-440c-9b66-9712ed982479",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
107
client/assets/scripts/App/AppStatus/AppStatusManager.ts
Normal file
107
client/assets/scripts/App/AppStatus/AppStatusManager.ts
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "191d542e-df2a-43a0-998c-4daefe65c598",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
396
client/assets/scripts/App/AppStatus/README.md
Normal file
396
client/assets/scripts/App/AppStatus/README.md
Normal file
@@ -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<void>;
|
||||
|
||||
// 初始化并连接网络
|
||||
private async initAndConnectNet(): Promise<void>;
|
||||
|
||||
// 退出启动状态
|
||||
onExit(): void;
|
||||
}
|
||||
```
|
||||
|
||||
**执行流程**:
|
||||
1. 设置服务协议
|
||||
2. 初始化网络配置
|
||||
3. 监听网络事件
|
||||
4. 连接服务器
|
||||
5. 连接成功后切换到登录状态
|
||||
|
||||
### AppStatusLogin - 登录状态
|
||||
|
||||
**职责**: 显示登录界面,处理登录逻辑
|
||||
|
||||
```typescript
|
||||
class AppStatusLogin extends BaseState {
|
||||
constructor(fsm: FSM);
|
||||
|
||||
// 进入登录状态
|
||||
async onEnter(params?: any): Promise<void>;
|
||||
|
||||
// 显示登录 UI
|
||||
private async showLoginUI(): Promise<void>;
|
||||
|
||||
// 退出登录状态
|
||||
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<void>;
|
||||
|
||||
// 加载游戏场景
|
||||
private async loadGameScene(): Promise<void>;
|
||||
|
||||
// 初始化游戏
|
||||
private async initGame(): Promise<void>;
|
||||
|
||||
// 监听服务器广播消息
|
||||
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<ReqLogin, ResLogin>('Login', {
|
||||
account: account
|
||||
});
|
||||
|
||||
// 登录成功后切换状态
|
||||
if (result && result.success) {
|
||||
AppStatusManager.getInstance().changeState('Game', {
|
||||
player: result.player,
|
||||
isNewPlayer: result.isNewPlayer
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Game 状态
|
||||
|
||||
```typescript
|
||||
// 监听服务器广播
|
||||
netManager.listenMsg<MsgPlayerJoin>('PlayerJoin', (msg) => {
|
||||
console.log(`玩家 ${msg.playerName} 加入游戏`);
|
||||
// 在场景中创建其他玩家
|
||||
});
|
||||
|
||||
netManager.listenMsg<MsgPlayerMove>('PlayerMove', (msg) => {
|
||||
console.log(`玩家 ${msg.playerName} 移动`);
|
||||
// 更新其他玩家位置
|
||||
});
|
||||
|
||||
// 发送 API
|
||||
const result = await netManager.callApi<ReqMove, ResMove>('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) - 登录模块
|
||||
9
client/assets/scripts/CC.meta
Normal file
9
client/assets/scripts/CC.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "4602b30b-05bf-465d-8537-b3afbbc83fb0",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user