import { Node, Vec3, instantiate, Prefab } from 'cc'; import { NetManager } from '../../Framework/Net/NetManager'; import { ResMgr } from '../../Framework/ResMgr/ResMgr'; import { MsgPlayerJoin } from '../../Shared/protocols/MsgPlayerJoin'; import { MsgPlayerMove } from '../../Shared/protocols/MsgPlayerMove'; import { PlayerInfo } from '../../Shared/protocols/PtlLogin'; import { PlayerController } from './PlayerController'; import { RemotePlayer } from './RemotePlayer'; /** * World 世界管理器 * 负责管理游戏世界中的所有玩家 * 包括本地玩家和远程玩家的创建、更新和销毁 */ export class World { private static instance: World = null; /** 世界根节点 */ private worldRoot: Node = null; /** 本地玩家信息 */ private localPlayer: PlayerInfo = null; /** 本地玩家控制器 */ private localPlayerController: PlayerController = null; /** 本地玩家节点 */ private localPlayerNode: Node = null; /** 远程玩家列表 Map */ private remotePlayers: Map = new Map(); /** 玩家模型预制体 */ private playerPrefab: Prefab = null; private constructor() {} public static getInstance(): World { if (!World.instance) { World.instance = new World(); } return World.instance; } /** * 初始化世界 * @param worldRoot 世界根节点 * @param localPlayer 本地玩家信息 */ public async init(worldRoot: Node, localPlayer: PlayerInfo): Promise { this.worldRoot = worldRoot; this.localPlayer = localPlayer; // 加载玩家模型预制体 await this.loadPlayerPrefab(); // 注册网络消息监听 this.registerNetworkListeners(); // 创建本地玩家 await this.createLocalPlayer(); console.log('[World] 世界初始化完成'); } /** * 加载玩家模型预制体 */ private async loadPlayerPrefab(): Promise { try { this.playerPrefab = await ResMgr.getInstance().load('resources', 'res://Actor/M1/M1', Prefab); console.log('[World] 玩家模型预制体加载成功'); } catch (error) { console.error('[World] 加载玩家模型预制体失败:', error); } } /** * 注册网络消息监听 */ private registerNetworkListeners(): void { const netManager = NetManager.getInstance(); // 监听玩家加入消息 netManager.listenMsg('PlayerJoin', (msg: MsgPlayerJoin) => { this.onPlayerJoin(msg); }); // 监听玩家移动消息 netManager.listenMsg('PlayerMove', (msg: MsgPlayerMove) => { this.onPlayerMove(msg); }); console.log('[World] 网络消息监听注册完成'); } /** * 创建本地玩家 */ private async createLocalPlayer(): Promise { if (!this.playerPrefab) { console.error('[World] 玩家模型预制体未加载'); return; } // 实例化玩家节点 this.localPlayerNode = instantiate(this.playerPrefab); this.localPlayerNode.name = `Player_${this.localPlayer.id}_Local`; this.localPlayerNode.setPosition(this.localPlayer.position.x, 0, this.localPlayer.position.y); this.worldRoot.addChild(this.localPlayerNode); // 创建本地玩家控制器 this.localPlayerController = this.localPlayerNode.addComponent(PlayerController); this.localPlayerController.init(this.localPlayer); console.log('[World] 本地玩家创建完成:', this.localPlayer.name); } /** * 处理玩家加入消息 */ private onPlayerJoin(msg: MsgPlayerJoin): void { console.log('[World] 玩家加入:', msg.playerName); // 如果是本地玩家,不处理 if (msg.playerId === this.localPlayer.id) { return; } // 创建远程玩家 this.createRemotePlayer(msg); } /** * 创建远程玩家 */ private async createRemotePlayer(msg: MsgPlayerJoin): Promise { if (!this.playerPrefab) { console.error('[World] 玩家模型预制体未加载'); return; } // 检查是否已存在 if (this.remotePlayers.has(msg.playerId)) { console.warn('[World] 远程玩家已存在:', msg.playerId); return; } // 实例化玩家节点 const playerNode = instantiate(this.playerPrefab); playerNode.name = `Player_${msg.playerId}_Remote`; playerNode.setPosition(msg.position.x, 0, msg.position.y); this.worldRoot.addChild(playerNode); // 创建远程玩家控制器 const remotePlayer = new RemotePlayer(); remotePlayer.init(playerNode, msg.playerId, msg.playerName, msg.position); this.remotePlayers.set(msg.playerId, remotePlayer); console.log('[World] 远程玩家创建完成:', msg.playerName); } /** * 处理玩家移动消息 */ private onPlayerMove(msg: MsgPlayerMove): void { // 如果是本地玩家,不处理 if (msg.playerId === this.localPlayer.id) { return; } // 更新远程玩家位置 const remotePlayer = this.remotePlayers.get(msg.playerId); if (remotePlayer) { remotePlayer.updatePosition(msg.position); } } /** * 获取本地玩家控制器 */ public getLocalPlayerController(): PlayerController { return this.localPlayerController; } /** * 销毁世界 */ public destroy(): void { // 注意: TSRPC 的 listenMsg 不提供取消监听的方法 // 在实际使用中,监听会在连接断开时自动清除 // 销毁本地玩家 if (this.localPlayerNode) { this.localPlayerNode.destroy(); this.localPlayerNode = null; } this.localPlayerController = null; // 销毁所有远程玩家 this.remotePlayers.forEach((remotePlayer) => { remotePlayer.destroy(); }); this.remotePlayers.clear(); // 释放资源 if (this.playerPrefab) { ResMgr.getInstance().release('resources', 'res://Actor/M1/M1'); this.playerPrefab = null; } this.worldRoot = null; this.localPlayer = null; console.log('[World] 世界已销毁'); } /** * 清理单例 */ public static clear(): void { if (World.instance) { World.instance.destroy(); World.instance = null; } } }