refactor(player): 优化角色移动方向更新和动画切换机制
- 移除冗余的方向计算和动画名称获取方法 - 简化移动方向更新逻辑,减少方向查看步数 - 新增垂直方向改变时的动画切换机制 - 优化移动过程中的方向判断和动画更新流程 - 移除不必要的路径点移动方法,简化代码结构
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止当前移动
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user