fix(hero cast): 调整敌我单位的目标选择逻辑
重构了SCastSystem中的目标查找逻辑,区分英雄和怪物的目标选择规则:英雄仅按X轴距离选择最近目标,怪物优先选择中路目标后再比较距离,同时更新了对应注释说明。
This commit is contained in:
@@ -549,7 +549,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const currentY = heroView.node.position.y;
|
||||
let nearest: HeroViewComp | null = null;
|
||||
let minDist = Infinity;
|
||||
let foundSameLane = false;
|
||||
let foundPreferredLane = false;
|
||||
const isHero = heroAttrs.fac === FacSet.HERO;
|
||||
|
||||
ecs.query(this.getHeroMatcher()).forEach(entity => {
|
||||
const attrs = entity.get(HeroAttrsComp);
|
||||
@@ -562,23 +563,29 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const distX = Math.abs(currentX - view.node.position.x);
|
||||
if (distX > maxRange) return;
|
||||
|
||||
const isSameLane = Math.abs(currentY - view.node.position.y) < 30; // 30为容差
|
||||
if (isHero) {
|
||||
// 英雄:单纯找X轴最近,无视路线
|
||||
if (distX < minDist) {
|
||||
minDist = distX;
|
||||
nearest = view;
|
||||
}
|
||||
} else {
|
||||
// 怪物:优先找中路目标
|
||||
const isMidLane = Math.abs(view.node.position.y) < 30; // 0 是中路
|
||||
|
||||
// 如果之前找到了同路目标,且当前不是同路,直接跳过
|
||||
if (foundSameLane && !isSameLane) return;
|
||||
if (foundPreferredLane && !isMidLane) return;
|
||||
|
||||
// 如果当前是同路,且之前没找到同路,则强制替换(同路优先)
|
||||
if (isSameLane && !foundSameLane) {
|
||||
foundSameLane = true;
|
||||
if (isMidLane && !foundPreferredLane) {
|
||||
foundPreferredLane = true;
|
||||
minDist = distX;
|
||||
nearest = view;
|
||||
return;
|
||||
}
|
||||
|
||||
if (distX >= minDist) return;
|
||||
minDist = distX;
|
||||
nearest = view;
|
||||
return;
|
||||
}
|
||||
|
||||
// 同等路况下比较距离
|
||||
if (distX >= minDist) return;
|
||||
minDist = distX;
|
||||
nearest = view;
|
||||
});
|
||||
return nearest;
|
||||
}
|
||||
@@ -586,7 +593,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
/**
|
||||
* 在施法距离内查找“最前排”敌人。
|
||||
* 依据施法者面向方向选择 x 轴上更前的目标。
|
||||
* 考虑三路设计:同路优先
|
||||
* 考虑三路设计:英雄找最前排,怪物优先找中路最前排
|
||||
*/
|
||||
private findFrontEnemyInRange(heroAttrs: HeroAttrsComp, heroView: HeroViewComp, maxRange: number, nearestEnemy: HeroViewComp): HeroViewComp | null {
|
||||
if (!heroView.node || !nearestEnemy.node) return null;
|
||||
@@ -595,7 +602,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const direction = nearestEnemy.node.position.x >= currentX ? 1 : -1;
|
||||
let frontEnemy: HeroViewComp | null = null;
|
||||
let edgeX = direction > 0 ? Infinity : -Infinity;
|
||||
let foundSameLane = false;
|
||||
let foundPreferredLane = false;
|
||||
const isHero = heroAttrs.fac === FacSet.HERO;
|
||||
|
||||
ecs.query(this.getHeroMatcher()).forEach(entity => {
|
||||
const attrs = entity.get(HeroAttrsComp);
|
||||
@@ -609,24 +617,38 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const dist = Math.abs(currentX - enemyX);
|
||||
if (dist > maxRange) return;
|
||||
|
||||
const isSameLane = Math.abs(currentY - view.node.position.y) < 30;
|
||||
if (foundSameLane && !isSameLane) return;
|
||||
|
||||
if (isSameLane && !foundSameLane) {
|
||||
foundSameLane = true;
|
||||
edgeX = enemyX;
|
||||
if (isHero) {
|
||||
// 英雄:无视路线,找X轴最前的
|
||||
if (direction > 0) {
|
||||
if (enemyX >= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
} else {
|
||||
if (enemyX <= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
}
|
||||
frontEnemy = view;
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction > 0) {
|
||||
if (enemyX >= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
} else {
|
||||
if (enemyX <= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
// 怪物:优先找中路最前排的
|
||||
const isMidLane = Math.abs(view.node.position.y) < 30;
|
||||
|
||||
if (foundPreferredLane && !isMidLane) return;
|
||||
|
||||
if (isMidLane && !foundPreferredLane) {
|
||||
foundPreferredLane = true;
|
||||
edgeX = enemyX;
|
||||
frontEnemy = view;
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction > 0) {
|
||||
if (enemyX >= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
} else {
|
||||
if (enemyX <= edgeX) return;
|
||||
edgeX = enemyX;
|
||||
}
|
||||
frontEnemy = view;
|
||||
}
|
||||
frontEnemy = view;
|
||||
});
|
||||
return frontEnemy;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user