refactor(game): 重构英雄阵型站位逻辑,移除硬编码使用动态计算
- 删除 `resolveFormationTargetX` 的导入和调用 - 将 `processRangedFormationCombat` 重命名为 `processFormationCombat`,使其适用于所有英雄类型 - 新增 `getFormationSlotX` 方法,根据同阵营、同Y轴单位的战斗优先级和生成顺序动态计算站位点 - 在撤退逻辑中,增加对战斗优先级的检查,防止低优先级单位阻挡高优先级单位
This commit is contained in:
@@ -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;
|
||||
/** 近战同优先级在满足条件时可超车,不做阻挡 */
|
||||
|
||||
Reference in New Issue
Block a user