diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts index a46375a8..79ce73b9 100644 --- a/assets/script/game/hero/HeroAtkSystem.ts +++ b/assets/script/game/hero/HeroAtkSystem.ts @@ -17,6 +17,7 @@ import { mLogger } from "../common/Logger"; import { SkillTriggerHelper } from "./SkillTriggerHelper"; import { getMonsterGoldDrop } from "../map/RogueConfig"; import { MissionEconomy } from "../map/MissionEconomy"; +import { MoveComp } from "./MoveComp"; /** 最终伤害数据接口 * 用于封装一次攻击计算的所有结果数据 @@ -194,6 +195,17 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda if (targetView) { targetView.do_atked(damage, isCrit, damageEvent.s_uuid, knockbackExtra); targetView.playEnd(skillConf.endAnm); + + // 击退位移下沉到 MoveSystem:直接写入 knockbackVelocity,由 MoveSystem 每帧衰减并叠加位移 + const moveComp = target.get(MoveComp); + if (moveComp) { + const dist = FightSet.BACK_RANG + knockbackExtra; + const isHero = TAttrsComp.fac === FacSet.HERO; + // 击退初速度:0.1 秒时间常数衰减,总位移约等于 dist + const knockbackSpeed = dist * 16; + moveComp.knockbackVelocity = isHero ? -knockbackSpeed : knockbackSpeed; + } + if (isFrost) { TAttrsComp.toFrost(); targetView.in_iced(FightSet.FROST_TIME); diff --git a/assets/script/game/hero/HeroViewComp.ts b/assets/script/game/hero/HeroViewComp.ts index a8aa7a8e..2f64a928 100644 --- a/assets/script/game/hero/HeroViewComp.ts +++ b/assets/script/game/hero/HeroViewComp.ts @@ -415,28 +415,10 @@ export class HeroViewComp extends CCComp { this.showDamage(damage, isCrit); } - private isBackingUp: boolean = false; // 🔥 添加后退状态标记 - //后退 back(distance: number = 0) { - // 🔥 防止重复调用后退动画 - if (this.isBackingUp) return; - this.isBackingUp = true; // 🔥 设置后退状态 - - // 基础击退距离 + 额外距离强化,双方阵营统一 - const dist = FightSet.BACK_RANG + distance; - const isHero = this.model.fac == FacSet.HERO; - // 边界钳制:HERO 不越过 BoxSet.LETF_END,MON 不越过 BoxSet.RIGHT_END - const tx = isHero - ? Math.max(BoxSet.LETF_END, this.node.position.x - dist) - : Math.min(BoxSet.RIGHT_END, this.node.position.x + dist); - - tween(this.node) - .to(0.1, { position: v3(tx, this.node.position.y, 0) }) - .call(() => { - this.isBackingUp = false; // 🔥 动画完成后重置状态 - }) - .start(); + // 击退位移由 MoveSystem 统一处理,视图层只负责触发,不直接操作 position + // 具体击退速度由 HeroAtkSystem 在伤害结算后写入 MoveComp.knockbackVelocity } // 伤害计算和战斗逻辑已迁移到 HeroBattleSystem diff --git a/assets/script/game/hero/MoveComp.ts b/assets/script/game/hero/MoveComp.ts index bf1d7550..81ef2418 100644 --- a/assets/script/game/hero/MoveComp.ts +++ b/assets/script/game/hero/MoveComp.ts @@ -28,7 +28,7 @@ export class MoveComp extends ecs.Comp { baseY: number = 0; /** 出生序,用于同条件渲染排序稳定 */ spawnOrder: number = 0; - /** 击退速度(像素/秒),受击瞬间赋值,每帧指数衰减至 0 */ + /** 击退速度(像素/秒),受击瞬间由 HeroAtkSystem 赋值,MoveSystem 每帧指数衰减至 0 */ knockbackVelocity: number = 0; reset() { @@ -85,11 +85,25 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate return; } - /** 所有移动都锁定在 baseY,避免出现“漂移” */ + /** 所有移动都锁定在 baseY,避免出现"漂移" */ if (view.node.position.y !== move.baseY) { view.node.setPosition(view.node.position.x, move.baseY, 0); } + /** 击退位移:每帧叠加 knockbackVelocity 并指数衰减,与推进解耦 */ + if (Math.abs(move.knockbackVelocity) > 0.01) { + const newX = view.node.position.x + move.knockbackVelocity * this.dt; + const clampedX = this.clampByFacBoundary(newX, model.fac); + if (Math.abs(clampedX - view.node.position.x) > 0.01) { + view.node.setPosition(clampedX, view.node.position.y, 0); + } + // 时间常数 τ=0.1s:0.1 秒衰减到约 37%,0.3 秒衰减到约 5%,总位移 ≈ v0 * 0.0632 + move.knockbackVelocity *= Math.exp(-10 * this.dt); + if (Math.abs(move.knockbackVelocity) < 0.01) { + move.knockbackVelocity = 0; + } + } + /** 准备阶段:双方原地待命,不推进不索敌 */ if (!smc.mission.in_fight) { this.clearCombatTarget(model);