feat(英雄): 优化英雄移动和碰撞逻辑

fix由于 setScale 会影响物理判断,造成玩家角色多次被攻击触发回调
- 添加英雄移动方向缓存避免频繁转向
- 优化英雄碰撞器初始状态管理
- 修复英雄后退动画重复触发问题
- 调整部分英雄prefab的碰撞组和传感器设置
This commit is contained in:
2025-11-03 13:10:43 +08:00
parent 5bd2e15fb5
commit d089699c36
16 changed files with 70 additions and 35 deletions

View File

@@ -15,11 +15,14 @@ export class HeroMoveComp extends ecs.Comp {
targetX: number = 0;
/** 是否处于移动状态 */
moving: boolean = true;
/** 当前朝向缓存避免频繁setScale */
currentFacing: number = 1;
reset() {
this.direction = 1;
this.targetX = 0;
this.moving = true;
this.currentFacing = 1;
}
}
@@ -73,12 +76,10 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
// 根据敌人位置调整移动方向和朝向
if (enemyX > currentX) {
move.direction = 1; // 向右移动
view.node.setScale(1, 1, 1); // 面向右侧
view.node.getChildByName("top").setScale(1, 1, 1); // 面向右侧
this.setFacing(view, move, 1); // 🔥 使用优化的转向方法
} else {
move.direction = -1; // 向左移动
view.node.setScale(-1, 1, 1); // 面向左侧
view.node.getChildByName("top").setScale(-1, 1, 1); // 面向左侧
this.setFacing(view, move, -1); // 🔥 使用优化的转向方法
}
// 继续向敌人方向移动
@@ -112,14 +113,8 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
const delta = (model.Attrs[Attrs.SPEED]/3) * this.dt * direction;
const newX = view.node.position.x + delta;
// 设置朝向
if (direction === 1) {
view.node.setScale(1, 1, 1); // 面向右侧
view.node.getChildByName("top").setScale(1, 1, 1); // 面向右侧
} else {
view.node.setScale(-1, 1, 1); // 面向左侧
view.node.getChildByName("top").setScale(-1, 1, 1); // 面向左侧
}
// 🔥 使用优化的转向方法
this.setFacing(view, move, direction);
// 确保不会超过目标位置
if (direction === 1 && newX > finalTargetX) {
@@ -134,8 +129,7 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
view.status_change("idle");
// 到达目标位置后,面向右侧(敌人方向)
move.direction = 1;
view.node.setScale(1, 1, 1); // 面向右侧
view.node.getChildByName("top").setScale(1, 1, 1); // 面向右侧
this.setFacing(view, move, 1); // 🔥 使用优化的转向方法
}
} else {
view.status_change("idle");
@@ -143,6 +137,24 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
}
}
/**
* 🔥 优化的转向方法只在真正需要改变朝向时才调用setScale
* 避免频繁的setScale调用导致碰撞器重新计算
*/
private setFacing(view: HeroViewComp, move: HeroMoveComp, newFacing: number) {
// 只有当朝向真正改变时才更新
if (move.currentFacing !== newFacing) {
move.currentFacing = newFacing;
view.node.setScale(newFacing, 1, 1);
// 安全获取top节点
const topNode = view.node.getChildByName("top");
if (topNode) {
topNode.setScale(newFacing, 1, 1);
}
}
}
/** 检查是否存在敌人 */
private checkEnemiesExist(entity: ecs.Entity): boolean {
const team = entity.get(HeroAttrsComp).fac;