From df0dedba752245123166c9526dd0e9724e35f6e2 Mon Sep 17 00:00:00 2001 From: panFD Date: Fri, 14 Aug 2026 00:36:26 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=95=B4=E7=90=86=E6=8A=80?= =?UTF-8?q?=E8=83=BD=E4=B8=8E=E6=88=98=E6=96=97=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=8E=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增技能飞行距离配置项,支持自定义直线技能飞行距离 2. 调整英雄后退击退范围从30改为20 3. 重构击退逻辑,统一敌我双方的边界钳制处理 4. 优化Boss数值配置,固定基础面板为初始英雄2倍强度 5. 修正技能6006的动画资源引用为atk1 6. 调整近战英雄默认停火距离从80改为60 7. 更新注释文档与配置注释,优化代码可读性 --- .../resources/game/skill/anm/atk/atk01.anim | 229 +++++++++++++++++- assets/resources/game/skill/atk/atk1.prefab | 1 + assets/script/game/common/config/GameSet.ts | 2 +- assets/script/game/common/config/SkillSet.ts | 2 +- assets/script/game/common/config/heroSet.ts | 3 +- assets/script/game/hero/HeroViewComp.ts | 36 +-- assets/script/game/hero/MoveComp.ts | 5 +- assets/script/game/map/RogueConfig.ts | 30 ++- assets/script/game/skill/SMoveComp.ts | 4 + assets/script/game/skill/SMoveSystem.ts | 39 ++- assets/script/game/skill/Skill.ts | 1 + assets/script/game/skill/SkillView.ts | 4 + 12 files changed, 301 insertions(+), 55 deletions(-) diff --git a/assets/resources/game/skill/anm/atk/atk01.anim b/assets/resources/game/skill/anm/atk/atk01.anim index 148d143b..74e3385e 100644 --- a/assets/resources/game/skill/anm/atk/atk01.anim +++ b/assets/resources/game/skill/anm/atk/atk01.anim @@ -11,9 +11,13 @@ "speed": 1, "wrapMode": 1, "enableTrsBlending": false, - "_duration": 0, + "_duration": 0.125, "_hash": 500763545, - "_tracks": [], + "_tracks": [ + { + "__id__": 1 + } + ], "_exoticAnimation": null, "_events": [ { @@ -29,10 +33,229 @@ ], "_embeddedPlayers": [], "_additiveSettings": { - "__id__": 1 + "__id__": 12 }, "_auxiliaryCurveEntries": [] }, + { + "__type__": "cc.animation.VectorTrack", + "_binding": { + "__type__": "cc.animation.TrackBinding", + "path": { + "__id__": 2 + }, + "proxy": null + }, + "_channels": [ + { + "__id__": 4 + }, + { + "__id__": 6 + }, + { + "__id__": 8 + }, + { + "__id__": 10 + } + ], + "_nComponents": 3 + }, + { + "__type__": "cc.animation.TrackPath", + "_paths": [ + { + "__id__": 3 + }, + "scale" + ] + }, + { + "__type__": "cc.animation.HierarchyPath", + "path": "Node" + }, + { + "__type__": "cc.animation.Channel", + "_curve": { + "__id__": 5 + } + }, + { + "__type__": "cc.RealCurve", + "_times": [ + 0, + 0.08333333333333333, + 0.125 + ], + "_values": [ + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1.2999999523162842, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": null + }, + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1.2999999523162842, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": { + "tangentMode": 0 + } + }, + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1.2999999523162842, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": null + } + ], + "preExtrapolation": 1, + "postExtrapolation": 1 + }, + { + "__type__": "cc.animation.Channel", + "_curve": { + "__id__": 7 + } + }, + { + "__type__": "cc.RealCurve", + "_times": [ + 0, + 0.08333333333333333, + 0.125 + ], + "_values": [ + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1.100000023841858, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": null + }, + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1.100000023841858, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": { + "tangentMode": 0 + } + }, + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1.100000023841858, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": null + } + ], + "preExtrapolation": 1, + "postExtrapolation": 1 + }, + { + "__type__": "cc.animation.Channel", + "_curve": { + "__id__": 9 + } + }, + { + "__type__": "cc.RealCurve", + "_times": [ + 0, + 0.08333333333333333, + 0.125 + ], + "_values": [ + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": null + }, + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": { + "tangentMode": 0 + } + }, + { + "__type__": "cc.RealKeyframeValue", + "interpolationMode": 0, + "tangentWeightMode": 0, + "value": 1, + "rightTangent": 0, + "rightTangentWeight": 1, + "leftTangent": 0, + "leftTangentWeight": 1, + "easingMethod": 0, + "__editorExtras__": null + } + ], + "preExtrapolation": 1, + "postExtrapolation": 1 + }, + { + "__type__": "cc.animation.Channel", + "_curve": { + "__id__": 11 + } + }, + { + "__type__": "cc.RealCurve", + "_times": [], + "_values": [], + "preExtrapolation": 1, + "postExtrapolation": 1 + }, { "__type__": "cc.AnimationClipAdditiveSettings", "enabled": false, diff --git a/assets/resources/game/skill/atk/atk1.prefab b/assets/resources/game/skill/atk/atk1.prefab index e50d784f..4246477d 100644 --- a/assets/resources/game/skill/atk/atk1.prefab +++ b/assets/resources/game/skill/atk/atk1.prefab @@ -254,6 +254,7 @@ "endType": 0, "speed": 720, "time": 0, + "distance": 100, "_id": "" }, { diff --git a/assets/script/game/common/config/GameSet.ts b/assets/script/game/common/config/GameSet.ts index 4c831581..f893e018 100644 --- a/assets/script/game/common/config/GameSet.ts +++ b/assets/script/game/common/config/GameSet.ts @@ -37,7 +37,7 @@ export enum FightSet { /** 英雄属性随等级成长的倍率(ap/hp = base * MULTIPLIER^(lv-1)) */ HERO_LV_MULTIPLIER = 2, // BACK_RANG=30,//后退范围 - BACK_RANG = 30,//后退范围 + BACK_RANG = 20,//后退范围 FiIGHT_TIME = 30,//战斗时间 FROST_TIME = 3,//冰冻时间 STUN_TIME = 2,//击晕时间 diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index f3ee6bd9..ec012c08 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -239,7 +239,7 @@ export const SkillSet: Record = { RType: RType.bezier, EType: EType.collision, info: "造成攻击力100%的伤害", }, 6006: { - uuid: 6006, name: "攻击", sp_name: "atk", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk", + uuid: 6006, name: "攻击", sp_name: "atk1", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk", DTType: DTType.single, ap: 100, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.Melee, is_accel: true, RType: RType.bezier, EType: EType.collision, info: "造成攻击力100%的伤害", }, diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 620869d5..7cf8ccd8 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -837,7 +837,8 @@ export const HeroInfo: Record = { skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } }, info: "后排召唤系法师怪" }, - // BOSS怪物 — 与6006同基准,以高HP压场,血量经 BOSS_HP_BONUS_MUL 单独放大 + // BOSS怪物 — 本表 hp/ap 仅作外观/技能档位参考,运行时面板由 RogueConfig 的 + // BOSS_BASE_HP / BOSS_BASE_AP(初始英雄 2 倍强度)统一决定,不读取本表数值 6101: { uuid: 6101, name: "兽人首领-双刀战士", path: "mb1", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1200, ap: 24, speed: 120, skills: { 6006: { uuid: 6006, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } }, info: "前排Boss, 攻速型" diff --git a/assets/script/game/hero/HeroViewComp.ts b/assets/script/game/hero/HeroViewComp.ts index 057bdcb8..a8aa7a8e 100644 --- a/assets/script/game/hero/HeroViewComp.ts +++ b/assets/script/game/hero/HeroViewComp.ts @@ -423,30 +423,20 @@ export class HeroViewComp extends CCComp { if (this.isBackingUp) return; this.isBackingUp = true; // 🔥 设置后退状态 - if (this.model.fac == FacSet.MON) { - // 基础击退距离,加上额外的距离强化 - let dist = FightSet.BACK_RANG + distance; - let tx = this.node.position.x + dist; - if (tx > 320) tx = 320; - tween(this.node) - .to(0.1, { position: v3(tx, this.node.position.y, 0) }) - .call(() => { - this.isBackingUp = false; // 🔥 动画完成后重置状态 - }) - .start(); - } + // 基础击退距离 + 额外距离强化,双方阵营统一 + 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); - if (this.model.fac == FacSet.HERO) { - let dist = 5 + distance; - let tx = this.node.position.x - dist; - if (tx < -320) tx = -320; - tween(this.node) - .to(0.1, { position: v3(tx, this.node.position.y, 0) }) - .call(() => { - this.isBackingUp = false; // 🔥 动画完成后重置状态 - }) - .start(); - } + tween(this.node) + .to(0.1, { position: v3(tx, this.node.position.y, 0) }) + .call(() => { + this.isBackingUp = false; // 🔥 动画完成后重置状态 + }) + .start(); } // 伤害计算和战斗逻辑已迁移到 HeroBattleSystem diff --git a/assets/script/game/hero/MoveComp.ts b/assets/script/game/hero/MoveComp.ts index cff184b5..bf1d7550 100644 --- a/assets/script/game/hero/MoveComp.ts +++ b/assets/script/game/hero/MoveComp.ts @@ -28,6 +28,8 @@ export class MoveComp extends ecs.Comp { baseY: number = 0; /** 出生序,用于同条件渲染排序稳定 */ spawnOrder: number = 0; + /** 击退速度(像素/秒),受击瞬间赋值,每帧指数衰减至 0 */ + knockbackVelocity: number = 0; reset() { this.direction = 1; @@ -35,6 +37,7 @@ export class MoveComp extends ecs.Comp { this.moving = true; this.baseY = 0; this.spawnOrder = 0; + this.knockbackVelocity = 0; } } @@ -146,7 +149,7 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate const dist = Math.abs(selfX - enemyX); const attackRange = model.dis; /** 近战贴身作战:攻击距离 dis(100) 大于技能范围(60),推进到与敌人相隔 60 才停下,保证技能可命中且不过度贴身 */ - const stopRange = model.type === 0 ? 80 : attackRange; + const stopRange = model.type === 0 ? 60 : attackRange; const inRange = dist <= stopRange; if (inRange) { diff --git a/assets/script/game/map/RogueConfig.ts b/assets/script/game/map/RogueConfig.ts index b2b4f453..c266293e 100644 --- a/assets/script/game/map/RogueConfig.ts +++ b/assets/script/game/map/RogueConfig.ts @@ -14,9 +14,10 @@ * 3. RogueSpawningEngine - 生成引擎(基础属性 × 可调系数) * * 核心公式(基础属性 × 可调系数): - * 怪物 hp = HeroInfo 基础hp × MON_HP_MUL(Boss 额外 × BOSS_HP_BONUS_MUL) - * 怪物 ap = HeroInfo 基础ap × MON_AP_MUL - * 怪物基础面板与 1 级英雄持平(近战镜像 hp300/ap22/cd1.8),默认系数校准为 + * 小怪 hp = HeroInfo 基础hp × MON_HP_MUL,小怪 ap = HeroInfo 基础ap × MON_AP_MUL + * Boss 基础面板固定为初始英雄 2 倍强度(BOSS_BASE_HP/BOSS_BASE_AP),与小怪共用同一套系数, + * 场上 Boss 恰好为小怪 2 倍强度(如需额外压场可调 BOSS_HP_BONUS_MUL)。 + * 小怪基础面板与 1 级英雄持平(近战镜像 hp300/ap22/cd1.8),默认系数校准为 * 整场战斗(3 英雄 vs 4 小怪 + 1 Boss)双方对砍 ≈ WAVE_DURATION(30s)。 * 手感微调只改 MON_HP_MUL / MON_AP_MUL / BOSS_HP_BONUS_MUL 三个系数即可。 */ @@ -40,8 +41,14 @@ export const MON_HP_MUL = 2.6; /** 怪物攻击可调系数:最终 ap = HeroInfo 基础ap × MON_AP_MUL。 * 0.9 使 4 小怪+1 Boss 的总 DPS ≈ 20,30s 恰好磨光 3 英雄总血量(≈600) */ export const MON_AP_MUL = 0.9; -/** Boss 血量额外加成(在 MON_HP_MUL 之上乘算,突出压场定位) */ -export const BOSS_HP_BONUS_MUL = 1.6; + +/** Boss 基础面板 = 初始英雄基准(hp300/ap22)× 2 倍强度, + * 不读取 Boss HeroInfo 的差异化高基础值,避免数值膨胀 */ +export const BOSS_BASE_HP = 600; +export const BOSS_BASE_AP = 44; + +/** Boss 血量额外加成(在 MON_HP_MUL 之上乘算,默认 1.0 表示不再额外膨胀,保留作压场微调旋钮) */ +export const BOSS_HP_BONUS_MUL = 1.0; /** 战斗超时(秒):超过后强制结算整局(残留怪销毁并扣留存分) */ export const BATTLE_TIMEOUT = 90; @@ -398,7 +405,8 @@ export class RogueSpawningEngine { monsters.push(this.makeBoss()); } - // 属性缩放:基础属性 × 可调系数(Boss 血量额外加成),校准目标双方对砍 ≈ 30s + // 属性缩放:基础属性 × 可调系数(Boss 基础面板已是英雄 2 倍,BOSS_HP_BONUS_MUL 默认 1.0), + // 校准目标:Boss 场上强度恰为小怪 2 倍,双方对砍 ≈ 30s for (const m of monsters) { m.hp = Math.max(1, Math.round(m.hp * MON_HP_MUL * (m.isBoss ? BOSS_HP_BONUS_MUL : 1))); m.ap = Math.max(1, Math.round(m.ap * MON_AP_MUL)); @@ -451,7 +459,7 @@ export class RogueSpawningEngine { return monsters; } - /** 生成 Boss(基础血量带最终战加成,属性随后由总强度框架统一缩放) */ + /** 生成 Boss(基础面板固定为初始英雄 2 倍强度,属性随后由 generateBossCombo 统一系数缩放) */ private makeBoss(): GeneratedMonster { const isMeleeBoss = Math.random() < 0.5; const type = isMeleeBoss ? MonType.MeleeBoss : MonType.LongBoss; @@ -463,15 +471,11 @@ export class RogueSpawningEngine { } const uuid = uuids[Math.floor(Math.random() * uuids.length)]; - const baseInfo = HeroInfo[uuid]; - const baseHp = baseInfo ? baseInfo.hp : 500; - const baseAp = baseInfo ? baseInfo.ap : 30; - return { uuid, type, - hp: Math.round(baseHp * BOSS_HP_BONUS_MUL), - ap: baseAp, + hp: BOSS_BASE_HP, + ap: BOSS_BASE_AP, isBoss: true, spawnIndex: 0, // 占位值,由 generateBossCombo 统一分配 batch: 0, diff --git a/assets/script/game/skill/SMoveComp.ts b/assets/script/game/skill/SMoveComp.ts index dc34fc88..6647706f 100644 --- a/assets/script/game/skill/SMoveComp.ts +++ b/assets/script/game/skill/SMoveComp.ts @@ -74,6 +74,9 @@ export class SMoveDataComp extends ecs.Comp { /** 是否自动销毁(到达目标后) */ autoDestroy: boolean = true; + + /** 直线飞行距离(仅 runType=linear 生效,<=0 时延长终点飞出屏幕) */ + distance: number = 0; reset() { this.startPos.set(0, 0, 0); @@ -98,6 +101,7 @@ export class SMoveDataComp extends ecs.Comp { this.startTime = 0; this.totalTime = 0; this.autoDestroy = true; + this.distance = 0; } /** diff --git a/assets/script/game/skill/SMoveSystem.ts b/assets/script/game/skill/SMoveSystem.ts index 2cfa510d..81495f35 100644 --- a/assets/script/game/skill/SMoveSystem.ts +++ b/assets/script/game/skill/SMoveSystem.ts @@ -83,21 +83,36 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate const direction = new Vec3(); Vec3.subtract(direction, originTargetPos, adjustedStartPos); - // 延长终止点,统一消亡点的x坐标为 +-500 - const targetX = moveComp.scale > 0 ? 500 : -500; - let targetY = originTargetPos.y; + let adjustedTargetPos: Vec3; + if (moveComp.distance > 0) { + // 距离模式:沿起始指向目标的方向飞行固定距离 + if (direction.length() < 0.01) { + // 起终点重合时退化为按朝向水平飞行 + direction.set(moveComp.scale > 0 ? 1 : -1, 0, 0); + } + direction.normalize(); + adjustedTargetPos = v3( + adjustedStartPos.x + direction.x * moveComp.distance, + adjustedStartPos.y + direction.y * moveComp.distance, + originTargetPos.z + ); + } else { + // 延长终止点,统一消亡点的x坐标为 +-500 + const targetX = moveComp.scale > 0 ? 500 : -500; + let targetY = originTargetPos.y; - if (Math.abs(direction.x) > 0.01) { - const slope = direction.y / direction.x; - targetY = adjustedStartPos.y + slope * (targetX - adjustedStartPos.x); + if (Math.abs(direction.x) > 0.01) { + const slope = direction.y / direction.x; + targetY = adjustedStartPos.y + slope * (targetX - adjustedStartPos.x); + } + + adjustedTargetPos = v3( + targetX, + targetY, + originTargetPos.z + ); } - const adjustedTargetPos = v3( - targetX, - targetY, - originTargetPos.z - ); - moveComp.startPos.set(adjustedStartPos); moveComp.targetPos.set(adjustedTargetPos); node.setPosition(adjustedStartPos); diff --git a/assets/script/game/skill/Skill.ts b/assets/script/game/skill/Skill.ts index 08f3d9cb..5fa70e1f 100644 --- a/assets/script/game/skill/Skill.ts +++ b/assets/script/game/skill/Skill.ts @@ -184,6 +184,7 @@ export class Skill extends ecs.Entity { // 从SkillView获取移动参数,位置初始化由SMoveSystem统一处理 sMoveCom.atk_x = SView.atk_x; sMoveCom.atk_y = SView.atk_y; + sMoveCom.distance = SView.distance; if (SView.endType === EType.timeEnd) { let sTimeCom = this.get(StimeDataComp); diff --git a/assets/script/game/skill/SkillView.ts b/assets/script/game/skill/SkillView.ts index cf7ebb4c..f2465939 100644 --- a/assets/script/game/skill/SkillView.ts +++ b/assets/script/game/skill/SkillView.ts @@ -38,6 +38,10 @@ export class SkillView extends CCComp { @property({ type: CCFloat, slide: true, range: [0, 30, 0.1], tooltip: "timeEnd 持续时间(秒)" }) time: number = 0; + /** 直线飞行距离(像素),仅 runType=linear 时生效(由 prefab 配置,<=0 时保持默认飞出屏幕的行为) */ + @property({ type: CCFloat, slide: true, range: [0, 2000, 10], tooltip: "直线飞行距离(仅 linear 生效)" }) + distance: number = 0; + private debugMode: boolean = false; anim: Animation = null;