refactor: 整理技能与战斗相关的配置与逻辑

1.  新增技能飞行距离配置项,支持自定义直线技能飞行距离
2.  调整英雄后退击退范围从30改为20
3.  重构击退逻辑,统一敌我双方的边界钳制处理
4.  优化Boss数值配置,固定基础面板为初始英雄2倍强度
5.  修正技能6006的动画资源引用为atk1
6.  调整近战英雄默认停火距离从80改为60
7.  更新注释文档与配置注释,优化代码可读性
This commit is contained in:
panFD
2026-08-14 00:36:26 +08:00
parent 4fee02d82e
commit df0dedba75
12 changed files with 301 additions and 55 deletions

View File

@@ -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,//击晕时间

View File

@@ -239,7 +239,7 @@ export const SkillSet: Record<number, SkillConfig> = {
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%的伤害",
},

View File

@@ -837,7 +837,8 @@ export const HeroInfo: Record<number, heroInfo> = {
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, 攻速型"

View File

@@ -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_ENDMON 不越过 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

View File

@@ -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) {

View File

@@ -14,9 +14,10 @@
* 3. RogueSpawningEngine - 生成引擎(基础属性 × 可调系数)
*
* 核心公式(基础属性 × 可调系数):
* 怪 hp = HeroInfo 基础hp × MON_HP_MULBoss 额外 × 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 ≈ 2030s 恰好磨光 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,

View File

@@ -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;
}
/**

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;