import { _decorator, Component, Node, EventKeyboard, KeyCode, Input, input, Vec3 } from 'cc'; import { NetManager } from '../../Framework/Net/NetManager'; import { ReqMove, ResMove } from '../../Shared/protocols/PtlMove'; import { PlayerInfo } from '../../Shared/protocols/PtlLogin'; import { RoleController } from '../../CC/RoleController'; const { ccclass } = _decorator; /** * PlayerController 本地玩家控制器 * 负责处理本地玩家的输入、移动和动画 */ @ccclass('PlayerController') export class PlayerController extends Component { /** 玩家信息 */ private playerInfo: PlayerInfo = null; /** 角色控制器(控制动画) */ private roleController: RoleController = null; /** 移动速度 */ private moveSpeed: number = 5; /** 当前移动方向 */ private moveDirection: Vec3 = new Vec3(0, 0, 0); /** 按键状态 */ private keyStates: Map = new Map(); /** 是否正在移动 */ private isMoving: boolean = false; /** 上次发送移动请求的位置 */ private lastSentPosition: Vec3 = new Vec3(); /** 移动阈值(超过这个距离才发送移动请求) */ private moveSendThreshold: number = 0.5; /** * 初始化玩家控制器 */ public init(playerInfo: PlayerInfo): void { this.playerInfo = playerInfo; this.lastSentPosition.set(playerInfo.position.x, 0, playerInfo.position.y); // 获取 RoleController 组件 this.roleController = this.node.getComponentInChildren(RoleController); if (!this.roleController) { console.warn('[PlayerController] 未找到 RoleController 组件'); } else { // 初始播放待机动画 this.roleController.PlayAnimation('idle', true); } console.log('[PlayerController] 初始化完成:', playerInfo.name); } protected onEnable(): void { // 注册键盘事件 input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this); input.on(Input.EventType.KEY_UP, this.onKeyUp, this); } protected onDisable(): void { // 取消注册键盘事件 input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this); input.off(Input.EventType.KEY_UP, this.onKeyUp, this); } /** * 键盘按下事件 */ private onKeyDown(event: EventKeyboard): void { this.keyStates.set(event.keyCode, true); } /** * 键盘抬起事件 */ private onKeyUp(event: EventKeyboard): void { this.keyStates.set(event.keyCode, false); } protected update(dt: number): void { // 计算移动方向 this.updateMoveDirection(); // 如果有移动方向,移动角色 if (this.moveDirection.lengthSqr() > 0) { this.move(dt); } else { // 没有移动,播放待机动画 if (this.isMoving) { this.isMoving = false; if (this.roleController) { this.roleController.PlayAnimation('idle', true); } } } } /** * 更新移动方向 */ private updateMoveDirection(): void { this.moveDirection.set(0, 0, 0); // W - 向前 if (this.keyStates.get(KeyCode.KEY_W)) { this.moveDirection.z -= 1; } // S - 向后 if (this.keyStates.get(KeyCode.KEY_S)) { this.moveDirection.z += 1; } // A - 向左 if (this.keyStates.get(KeyCode.KEY_A)) { this.moveDirection.x -= 1; } // D - 向右 if (this.keyStates.get(KeyCode.KEY_D)) { this.moveDirection.x += 1; } // 归一化移动方向 if (this.moveDirection.lengthSqr() > 0) { this.moveDirection.normalize(); } } /** * 移动角色 */ private move(dt: number): void { // 计算移动增量 const moveOffset = this.moveDirection.clone().multiplyScalar(this.moveSpeed * dt); // 更新节点位置 const currentPos = this.node.position.clone(); currentPos.add(moveOffset); this.node.setPosition(currentPos); // 更新朝向(让角色面向移动方向) if (this.moveDirection.lengthSqr() > 0) { const targetAngle = Math.atan2(this.moveDirection.x, -this.moveDirection.z) * (180 / Math.PI); this.node.setRotationFromEuler(0, targetAngle, 0); } // 播放移动动画 if (!this.isMoving) { this.isMoving = true; if (this.roleController) { this.roleController.PlayAnimation('move', true); } } // 检查是否需要发送移动请求 this.checkSendMoveRequest(currentPos); } /** * 检查是否需要发送移动请求 */ private checkSendMoveRequest(currentPos: Vec3): void { const distance = Vec3.distance(currentPos, this.lastSentPosition); // 如果移动距离超过阈值,发送移动请求 if (distance >= this.moveSendThreshold) { this.sendMoveRequest(currentPos.x, currentPos.z); this.lastSentPosition.set(currentPos); } } /** * 发送移动请求到服务器 */ private async sendMoveRequest(x: number, z: number): Promise { try { const netManager = NetManager.getInstance(); const result = await netManager.callApi('Move', { x: x, y: z }); if (!result) { console.error('[PlayerController] 移动请求失败'); return; } // 服务器可能会修正位置,使用服务器返回的位置 if (result.position) { const serverPos = result.position; this.node.setPosition(serverPos.x, 0, serverPos.y); this.lastSentPosition.set(serverPos.x, 0, serverPos.y); } } catch (error) { console.error('[PlayerController] 发送移动请求异常:', error); } } /** * 获取玩家信息 */ public getPlayerInfo(): PlayerInfo { return this.playerInfo; } }