refactor(player): 优化角色移动方向更新和动画切换机制

- 移除冗余的方向计算和动画名称获取方法
- 简化移动方向更新逻辑,减少方向查看步数
- 新增垂直方向改变时的动画切换机制
- 优化移动过程中的方向判断和动画更新流程
- 移除不必要的路径点移动方法,简化代码结构
This commit is contained in:
richarjiang
2025-10-21 11:12:32 +08:00
parent 1b5fa721e6
commit 9363817fd4

View File

@@ -64,7 +64,7 @@ export class PlayerController extends Component {
private props: Node[] = [];
// 行走方向相关参数
private readonly directionLookAheadSteps = 2; // 更新方向时向前查看的路径节点数
private readonly directionLookAheadSteps = 1; // 更新方向时向前查看的路径节点数
private readonly minDirectionUpdateDistance = 1; // 小于该距离时不刷新方向,避免抖动
private guideNode: Node | null = null;
@@ -289,29 +289,6 @@ export class PlayerController extends Component {
return clampedPosition;
}
/**
* 根据移动方向获取对应的动画名称
* 现在只返回基础动画名称,不包含方向信息
*/
private getAnimationNameByDirection(currentPos: Vec3, targetPos: Vec3): string {
const deltaX = targetPos.x - currentPos.x;
const deltaY = targetPos.y - currentPos.y;
// 如果移动距离很小,保持当前动画
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance < 1) {
if (this.isCurrentAction('walk')) {
return 'walk';
}
return 'stand';
}
this.currentDirection = this.resolveDirectionFromDelta(deltaX, deltaY);
// 只返回基础动画名称,不包含方向信息
return 'walk';
}
/**
* 切换动画,避免不必要的切换
* 根据 this.currentDirection 来决定 player 的 scale 是否要取反,不再需要通过动画名称进行区分
@@ -414,13 +391,6 @@ export class PlayerController extends Component {
return animationName;
}
private isCurrentAction(action: string): boolean {
if (!this.currentAnimation) {
return false;
}
return this.normalizeAnimationAction(this.currentAnimation) === action;
}
private resolveDirectionFromDelta(
deltaX: number,
deltaY: number,
@@ -502,62 +472,6 @@ export class PlayerController extends Component {
return candidates;
}
/**
* 移动到路径中的下一个路径点
*/
private moveToNextWaypoint() {
if (this.isCurrentAction('attack') || this.isAttacking) {
return;
}
if (!this.player || this.currentPath.length === 0 || this.currentPathIndex >= this.currentPath.length) {
this.isMoving = false;
this.switchAnimation('stand');
console.log('路径移动完成');
return;
}
// 停止当前的移动tween
if (this.moveTween) {
this.moveTween.stop();
this.moveTween = null;
}
const targetPos = this.currentPath[this.currentPathIndex];
const currentPos = this.player.position;
// 计算移动距离和时间
const distance = Vec3.distance(currentPos, targetPos);
const moveTime = distance / this.moveSpeed;
console.log(`移动到路径点${this.currentPathIndex}: (${targetPos.x.toFixed(2)}, ${targetPos.y.toFixed(2)})`);
// 记录目标位置用于方向判断
this.lastTargetPosition.set(targetPos);
this.lastPosition.set(currentPos);
// 计算朝向下一个路径点的方向,而不是当前目标点
let nextPosForDirection = targetPos;
if (this.currentPathIndex < this.currentPath.length - 1) {
// 如果还有下一个路径点,使用下一个路径点作为方向参考
nextPosForDirection = this.currentPath[this.currentPathIndex + 1];
}
// 在移动前计算并设置方向(基于下一个路径点)
this.updateMovementDirectionOnce(currentPos, nextPosForDirection);
// 使用缓动移动到目标位置
this.moveTween = tween(this.player)
.to(moveTime, { position: targetPos }, {
easing: 'linear', // 使用线性插值,保持匀速移动
onComplete: () => {
this.currentPathIndex++;
this.moveToNextWaypoint();
}
})
.start();
}
/**
* 开始平滑路径移动
*/
@@ -665,7 +579,6 @@ export class PlayerController extends Component {
}
/**
* 在移动开始前计算一次方向(梦幻西游风格:点击一次屏幕只计算一次方向)
* 算法:优先判断水平方向(左/右),只有当水平方向不明显时才判断垂直方向
*/
private updateMovementDirectionOnce(startPos: Vec3, targetPos: Vec3) {
@@ -748,12 +661,49 @@ export class PlayerController extends Component {
// 只有当方向发生显著变化时才更新
if (newDirection !== this.currentDirection) {
const previousDirection = this.currentDirection;
this.currentDirection = newDirection;
// 更新玩家缩放(翻转)
this.updatePlayerScale();
console.log(`移动过程中更新方向: ${newDirection}`);
// 根据朝向改变更新移动动画
this.updateMovementAnimation(previousDirection, newDirection);
console.log(`移动过程中更新方向: ${previousDirection} -> ${newDirection}`);
}
}
/**
* 根据朝向改变更新移动动画
* @param previousDirection 之前的方向
* @param newDirection 新的方向
*/
private updateMovementAnimation(previousDirection: PlayerDirection, newDirection: PlayerDirection) {
if (!this.isMoving) {
return; // 只有在移动状态下才更新动画
}
// 检查是否需要切换动画(垂直方向改变时)
const previousVertical = this.isDirectionUp(previousDirection);
const newVertical = this.isDirectionUp(newDirection);
if (previousVertical !== newVertical) {
// 垂直方向改变,需要切换动画
this.switchAnimation('walk');
console.log(`垂直方向改变,切换移动动画: ${previousVertical ? '上' : '下'} -> ${newVertical ? '上' : '下'}`);
}
}
/**
* 判断方向是否向上
* @param direction 玩家方向
* @returns 是否向上
*/
private isDirectionUp(direction: PlayerDirection): boolean {
return direction === PlayerDirection.LeftUp || direction === PlayerDirection.RightUp;
}
/**
* 停止当前移动
*/