refactor(game): 重构英雄阵型站位逻辑,移除硬编码使用动态计算

- 删除 `resolveFormationTargetX` 的导入和调用
- 将 `processRangedFormationCombat` 重命名为 `processFormationCombat`,使其适用于所有英雄类型
- 新增 `getFormationSlotX` 方法,根据同阵营、同Y轴单位的战斗优先级和生成顺序动态计算站位点
- 在撤退逻辑中,增加对战斗优先级的检查,防止低优先级单位阻挡高优先级单位
This commit is contained in:
panw
2026-03-31 09:54:53 +08:00
parent 44dbded217
commit 6a0304b265

View File

@@ -3,7 +3,7 @@ import { HeroViewComp } from "./HeroViewComp";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { smc } from "../common/SingletonModuleComp";
import { FacSet } from "../common/config/GameSet";
import { HeroDisVal, HType, resolveFormationTargetX } from "../common/config/heroSet";
import { HeroDisVal, HType } from "../common/config/heroSet";
import { Node } from "cc";
@ecs.register('MoveComp')
@@ -200,21 +200,20 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
}
private processMeleeLogic(e: ecs.Entity, move: MoveComp, view: HeroViewComp, model: HeroAttrsComp, enemy: HeroViewComp) {
this.processRangedFormationCombat(move, view, model);
this.processFormationCombat(e, move, view, model);
}
private processMidLogic(e: ecs.Entity, move: MoveComp, view: HeroViewComp, model: HeroAttrsComp, enemy: HeroViewComp) {
this.processRangedFormationCombat(move, view, model);
this.processFormationCombat(e, move, view, model);
}
private processLongLogic(e: ecs.Entity, move: MoveComp, view: HeroViewComp, model: HeroAttrsComp, enemy: HeroViewComp) {
this.processRangedFormationCombat(move, view, model);
this.processFormationCombat(e, move, view, model);
}
private processRangedFormationCombat(move: MoveComp, view: HeroViewComp, model: HeroAttrsComp) {
private processFormationCombat(e: ecs.Entity, move: MoveComp, view: HeroViewComp, model: HeroAttrsComp) {
const currentX = view.node.position.x;
/** 中/远程不追人:强制回到自己职业站位点输出 */
const targetX = this.getFixedFormationX(model);
const targetX = this.getFormationSlotX(e, model, move.baseY);
move.targetX = targetX;
const needMoveToFormation = Math.abs(currentX - targetX) > 5;
if (needMoveToFormation) {
@@ -246,8 +245,7 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
private processReturnFormation(e: ecs.Entity, move: MoveComp, view: HeroViewComp, model: HeroAttrsComp) {
const currentX = view.node.position.x;
/** 脱战时所有类型都回职业站位点,保证阵型稳定 */
const targetX = this.getFixedFormationX(model);
const targetX = this.getFormationSlotX(e, model, move.baseY);
move.targetX = targetX;
if (Math.abs(currentX - targetX) > 5) {
@@ -266,17 +264,37 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
}
}
private getFixedFormationX(model: HeroAttrsComp): number {
/**
* 站位点来自 heroSet.resolveFormationTargetX
* - 近战 HType.Melee: FormationPointX=0
* - 中程 HType.Mid: FormationPointX=100
* - 远程 HType.Long: FormationPointX=180
* 阵营镜像规则:
* - HERO(FacSet.HERO=0):乘 -1 => 近战0 / 中程-100 / 远程-180
* - MON(FacSet.MON=1):乘 +1 => 近战0 / 中程100 / 远程180
*/
return resolveFormationTargetX(model.fac, model.type as HType);
private getFormationSlotX(self: ecs.Entity, model: HeroAttrsComp, baseY: number): number {
const cfg = this.facConfigs[model.fac] || this.facConfigs[FacSet.HERO];
const moveMinX = Math.min(cfg.moveBackX, cfg.moveFrontX);
const moveMaxX = Math.max(cfg.moveBackX, cfg.moveFrontX);
const forwardDir = model.fac === FacSet.MON ? -1 : 1;
const sortedAllies: ecs.Entity[] = [];
ecs.query(this.getHeroMoveMatcher()).forEach(e => {
const attrs = e.get(HeroAttrsComp);
const view = e.get(HeroViewComp);
if (!attrs || !view?.node) return;
if (attrs.is_dead || attrs.is_reviving) return;
if (attrs.fac !== model.fac) return;
if (Math.abs(view.node.position.y - baseY) >= this.minSpacingY) return;
sortedAllies.push(e);
});
sortedAllies.sort((a, b) => {
const attrsA = a.get(HeroAttrsComp);
const attrsB = b.get(HeroAttrsComp);
const priorityA = attrsA ? this.getCombatPriority(attrsA) : 0;
const priorityB = attrsB ? this.getCombatPriority(attrsB) : 0;
if (priorityA !== priorityB) return priorityB - priorityA;
const moveA = a.get(MoveComp);
const moveB = b.get(MoveComp);
const orderA = moveA?.spawnOrder ?? 0;
const orderB = moveB?.spawnOrder ?? 0;
if (orderA !== orderB) return orderA - orderB;
return a.eid - b.eid;
});
const slotIndex = Math.max(0, sortedAllies.findIndex(entity => entity === self));
const targetX = 0 - forwardDir * slotIndex * this.allySpacingX;
return Math.max(moveMinX, Math.min(moveMaxX, targetX));
}
private moveEntity(view: HeroViewComp, direction: number, speed: number, stopAtX?: number) {
@@ -333,6 +351,9 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
if (attrs.fac !== fac) return;
if (Math.abs(view.node.position.y - baseY) >= this.minSpacingY) return;
const allyPriority = this.getCombatPriority(attrs);
const facForwardDir = fac === FacSet.MON ? -1 : 1;
const isRetreating = direction !== facForwardDir;
if (isRetreating && selfPriority < allyPriority) return;
if (allyPriority < selfPriority) return;
const x = view.node.position.x;
/** 近战同优先级在满足条件时可超车,不做阻挡 */