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;
|
const currentY = heroView.node.position.y;
|
||||||
let nearest: HeroViewComp | null = null;
|
let nearest: HeroViewComp | null = null;
|
||||||
let minDist = Infinity;
|
let minDist = Infinity;
|
||||||
let foundSameLane = false;
|
let foundPreferredLane = false;
|
||||||
|
const isHero = heroAttrs.fac === FacSet.HERO;
|
||||||
|
|
||||||
ecs.query(this.getHeroMatcher()).forEach(entity => {
|
ecs.query(this.getHeroMatcher()).forEach(entity => {
|
||||||
const attrs = entity.get(HeroAttrsComp);
|
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);
|
const distX = Math.abs(currentX - view.node.position.x);
|
||||||
if (distX > maxRange) return;
|
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 (foundPreferredLane && !isMidLane) return;
|
||||||
if (foundSameLane && !isSameLane) return;
|
|
||||||
|
|
||||||
// 如果当前是同路,且之前没找到同路,则强制替换(同路优先)
|
if (isMidLane && !foundPreferredLane) {
|
||||||
if (isSameLane && !foundSameLane) {
|
foundPreferredLane = true;
|
||||||
foundSameLane = true;
|
minDist = distX;
|
||||||
|
nearest = view;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distX >= minDist) return;
|
||||||
minDist = distX;
|
minDist = distX;
|
||||||
nearest = view;
|
nearest = view;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同等路况下比较距离
|
|
||||||
if (distX >= minDist) return;
|
|
||||||
minDist = distX;
|
|
||||||
nearest = view;
|
|
||||||
});
|
});
|
||||||
return nearest;
|
return nearest;
|
||||||
}
|
}
|
||||||
@@ -586,7 +593,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
/**
|
/**
|
||||||
* 在施法距离内查找“最前排”敌人。
|
* 在施法距离内查找“最前排”敌人。
|
||||||
* 依据施法者面向方向选择 x 轴上更前的目标。
|
* 依据施法者面向方向选择 x 轴上更前的目标。
|
||||||
* 考虑三路设计:同路优先
|
* 考虑三路设计:英雄找最前排,怪物优先找中路最前排
|
||||||
*/
|
*/
|
||||||
private findFrontEnemyInRange(heroAttrs: HeroAttrsComp, heroView: HeroViewComp, maxRange: number, nearestEnemy: HeroViewComp): HeroViewComp | null {
|
private findFrontEnemyInRange(heroAttrs: HeroAttrsComp, heroView: HeroViewComp, maxRange: number, nearestEnemy: HeroViewComp): HeroViewComp | null {
|
||||||
if (!heroView.node || !nearestEnemy.node) return 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;
|
const direction = nearestEnemy.node.position.x >= currentX ? 1 : -1;
|
||||||
let frontEnemy: HeroViewComp | null = null;
|
let frontEnemy: HeroViewComp | null = null;
|
||||||
let edgeX = direction > 0 ? Infinity : -Infinity;
|
let edgeX = direction > 0 ? Infinity : -Infinity;
|
||||||
let foundSameLane = false;
|
let foundPreferredLane = false;
|
||||||
|
const isHero = heroAttrs.fac === FacSet.HERO;
|
||||||
|
|
||||||
ecs.query(this.getHeroMatcher()).forEach(entity => {
|
ecs.query(this.getHeroMatcher()).forEach(entity => {
|
||||||
const attrs = entity.get(HeroAttrsComp);
|
const attrs = entity.get(HeroAttrsComp);
|
||||||
@@ -609,24 +617,38 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
const dist = Math.abs(currentX - enemyX);
|
const dist = Math.abs(currentX - enemyX);
|
||||||
if (dist > maxRange) return;
|
if (dist > maxRange) return;
|
||||||
|
|
||||||
const isSameLane = Math.abs(currentY - view.node.position.y) < 30;
|
if (isHero) {
|
||||||
if (foundSameLane && !isSameLane) return;
|
// 英雄:无视路线,找X轴最前的
|
||||||
|
if (direction > 0) {
|
||||||
if (isSameLane && !foundSameLane) {
|
if (enemyX >= edgeX) return;
|
||||||
foundSameLane = true;
|
edgeX = enemyX;
|
||||||
edgeX = enemyX;
|
} else {
|
||||||
|
if (enemyX <= edgeX) return;
|
||||||
|
edgeX = enemyX;
|
||||||
|
}
|
||||||
frontEnemy = view;
|
frontEnemy = view;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (direction > 0) {
|
|
||||||
if (enemyX >= edgeX) return;
|
|
||||||
edgeX = enemyX;
|
|
||||||
} else {
|
} 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;
|
return frontEnemy;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user