Files
rougelike-demo/client/assets/scripts/App/Game/RemotePlayer.ts
2025-12-14 23:35:08 +08:00

157 lines
4.3 KiB
TypeScript

import { Node, Vec3, Tween, tween } from 'cc';
import { Position } from '../../Shared/protocols/base';
import { RoleController } from '../../CC/RoleController';
/**
* RemotePlayer 远程玩家
* 负责管理远程玩家的显示和位置同步
*/
export class RemotePlayer {
/** 玩家节点 */
private playerNode: Node = null;
/** 玩家ID */
private playerId: string = '';
/** 玩家名称 */
private playerName: string = '';
/** 当前位置 */
private currentPosition: Vec3 = new Vec3();
/** 目标位置 */
private targetPosition: Vec3 = new Vec3();
/** 角色控制器(控制动画) */
private roleController: RoleController = null;
/** 移动补间 */
private moveTween: Tween<Node> = null;
/** 是否正在移动 */
private isMoving: boolean = false;
/**
* 初始化远程玩家
*/
public init(playerNode: Node, playerId: string, playerName: string, position: Position): void {
this.playerNode = playerNode;
this.playerId = playerId;
this.playerName = playerName;
this.currentPosition.set(position.x, 0, position.y);
this.targetPosition.set(position.x, 0, position.y);
// 获取 RoleController 组件
this.roleController = this.playerNode.getComponentInChildren(RoleController);
if (!this.roleController) {
console.warn('[RemotePlayer] 未找到 RoleController 组件');
} else {
// 初始播放待机动画
this.roleController.PlayAnimation('idle', true);
}
console.log('[RemotePlayer] 初始化完成:', playerName);
}
/**
* 更新位置
* 收到服务器广播的移动消息时调用
*/
public updatePosition(position: Position): void {
this.targetPosition.set(position.x, 0, position.y);
// 计算移动方向和距离
const direction = this.targetPosition.clone().subtract(this.currentPosition);
const distance = direction.length();
// 如果距离太小,不做处理
if (distance < 0.1) {
return;
}
// 停止之前的移动补间
if (this.moveTween) {
this.moveTween.stop();
this.moveTween = null;
}
// 计算朝向
if (distance > 0.01) {
const targetAngle = Math.atan2(direction.x, -direction.z) * (180 / Math.PI);
this.playerNode.setRotationFromEuler(0, targetAngle, 0);
}
// 播放移动动画
if (!this.isMoving) {
this.isMoving = true;
if (this.roleController) {
this.roleController.PlayAnimation('move', true);
}
}
// 计算移动时间(根据距离,假设速度为5单位/秒)
const moveSpeed = 5;
const moveDuration = distance / moveSpeed;
// 创建移动补间
this.moveTween = tween(this.playerNode)
.to(moveDuration, { position: this.targetPosition }, {
onUpdate: (target, ratio) => {
// 更新当前位置
this.currentPosition.set(this.playerNode.position);
},
onComplete: () => {
// 移动完成,播放待机动画
this.isMoving = false;
if (this.roleController) {
this.roleController.PlayAnimation('idle', true);
}
this.moveTween = null;
}
})
.start();
}
/**
* 获取玩家ID
*/
public getPlayerId(): string {
return this.playerId;
}
/**
* 获取玩家名称
*/
public getPlayerName(): string {
return this.playerName;
}
/**
* 获取玩家节点
*/
public getPlayerNode(): Node {
return this.playerNode;
}
/**
* 销毁远程玩家
*/
public destroy(): void {
// 停止移动补间
if (this.moveTween) {
this.moveTween.stop();
this.moveTween = null;
}
// 销毁节点
if (this.playerNode) {
this.playerNode.destroy();
this.playerNode = null;
}
this.roleController = null;
console.log('[RemotePlayer] 已销毁:', this.playerName);
}
}