import { _decorator, Component, Enum, Node } from 'cc'; import { PinballBootConfig, PinballBootMode, PinballBootResult, PinballBootstrap } from '../Modules/Pinball/Boot'; import { PinballManager } from '../Modules/Pinball/PinballManager'; const { ccclass, property } = _decorator; // 定义模式枚举 export enum RunMode { STANDALONE = 0, CLIENT_MULTIPLAYER = 1, SERVER_MULTIPLAYER = 2 } // 将枚举注册到Cocos Creator Enum(RunMode); // RunMode 到字符串的映射 const RunModeStrings = { [RunMode.STANDALONE]: 'standalone', [RunMode.CLIENT_MULTIPLAYER]: 'client-multiplayer', [RunMode.SERVER_MULTIPLAYER]: 'server-multiplayer' } as const; // RunMode 到 PinballBootMode 的映射 const RunModeToPinballBootMode = { [RunMode.STANDALONE]: PinballBootMode.STANDALONE, [RunMode.CLIENT_MULTIPLAYER]: PinballBootMode.CLIENT_MULTIPLAYER, [RunMode.SERVER_MULTIPLAYER]: PinballBootMode.SERVER_MULTIPLAYER } as const; @ccclass('ClientRunner') export class ClientRunner extends Component { @property({ type: Enum(RunMode), displayName: "运行模式", tooltip: '选择运行模式:单机/客户端多人/服务器多人' }) public mode: RunMode = RunMode.STANDALONE; @property({ type: Node, displayName: "主相机节点", tooltip: '主相机节点,用于渲染游戏画面' }) public cameraNode: Node = null; @property({ type: Node, displayName: "渲染容器", tooltip: '渲染容器节点,所有游戏对象将在此节点下渲染' }) public renderContainer: Node = null; @property({ type: Node, displayName: "UI容器", tooltip: 'UI容器节点,用于显示游戏UI界面' }) public uiContainer: Node = null; private pinballManager: PinballManager = null; private bootResult: PinballBootResult = null; async start() { console.log(`[ClientRunner] 开始启动,运行模式: ${this.getModeString()}`); // 使用 Bootstrap 启动游戏 await this.bootWithBootstrap(); } /** * 使用 Bootstrap 启动游戏 */ private async bootWithBootstrap(): Promise { try { // 创建启动配置 const config = this.createBootConfig(); // 使用 Bootstrap 启动 const bootstrap = PinballBootstrap.getInstance(); this.bootResult = await bootstrap.boot(this, config); if (this.bootResult.success) { this.pinballManager = this.bootResult.pinballManager; console.log(`[ClientRunner] 使用 Bootstrap 启动成功: ${this.bootResult.mode}`); } else { console.error(`[ClientRunner] Bootstrap 启动失败: ${this.bootResult.error}`); this.handleBootFailure(this.bootResult); } } catch (error) { console.error('[ClientRunner] Bootstrap 启动异常:', error); } } /** * 创建启动配置 */ private createBootConfig(): PinballBootConfig { // 将 RunMode 转换为 PinballBootMode const bootMode = this.convertRunModeToPinballBootMode(this.mode); // 使用默认配置并设置节点引用 const config = PinballBootstrap.createDefaultConfig(bootMode); config.cameraNode = this.cameraNode; config.renderContainer = this.renderContainer; config.uiContainer = this.uiContainer; // 根据模式添加特定配置 if (bootMode === PinballBootMode.CLIENT_MULTIPLAYER || bootMode === PinballBootMode.SERVER_MULTIPLAYER) { config.multiplayerConfig = { serverAddress: 'localhost:3000', // 默认服务器地址 playerName: 'Player1', roomId: 'default' }; } return config; } /** * 转换 RunMode 到 PinballBootMode */ private convertRunModeToPinballBootMode(runMode: RunMode): PinballBootMode { return RunModeToPinballBootMode[runMode] ?? PinballBootMode.STANDALONE; } /** * 处理启动失败 */ private handleBootFailure(result: PinballBootResult): void { console.error(`[ClientRunner] 启动失败 - 模式: ${result.mode}, 错误: ${result.error}`); // 可以在这里添加错误恢复逻辑,比如回退到 Standalone 模式 if (result.mode !== PinballBootMode.STANDALONE) { console.log('[ClientRunner] 尝试回退到 Standalone 模式...'); setTimeout(async () => { this.mode = RunMode.STANDALONE; await this.bootWithBootstrap(); }, 1000); } } update(deltaTime: number) { } onDestroy() { // 清理 PinballManager if (this.pinballManager) { this.pinballManager = null; } } /** * 获取 PinballManager 实例 */ public getPinballManager(): PinballManager | null { return this.pinballManager; } /** * 重启当前模式 */ public async restart(): Promise { console.log('[ClientRunner] 重启游戏...'); if (this.pinballManager) { await this.pinballManager.restartGame(); } else { // 如果没有 PinballManager,重新执行启动流程 await this.bootWithBootstrap(); } } /** * 切换模式并重启 */ public async switchMode(newMode: RunMode): Promise { console.log(`[ClientRunner] 切换模式从 ${this.getModeString()} 到 ${this.getModeStringForMode(newMode)}`); // 停止当前游戏 if (this.pinballManager) { await this.pinballManager.stopCurrentGame(); } // 设置新模式 this.mode = newMode; // 重新启动 await this.bootWithBootstrap(); } /** * 获取启动结果 */ public getBootResult(): PinballBootResult | null { return this.bootResult; } /** * 获取指定模式的字符串值 */ private getModeStringForMode(mode: RunMode): string { return RunModeStrings[mode] ?? 'standalone'; } /** * 获取当前模式的字符串值 * @returns 模式字符串 */ public getModeString(): string { return this.getModeStringForMode(this.mode); } }