From 9b35482b3c7ddc45d3711035dbb4870d412f22cb Mon Sep 17 00:00:00 2001 From: panw Date: Tue, 12 May 2026 16:32:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor(hero):=20=E7=BB=9F=E4=B8=80=E8=8B=B1?= =?UTF-8?q?=E9=9B=84=E6=94=BB=E5=87=BB=E5=B0=84=E7=A8=8B=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E5=B0=84=E7=A8=8B=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 将MoveSystem和MonMoveSystem中的硬编码射程常量替换为HeroDisVal统一配置 2. 调整近战英雄默认攻击射程为120,修正原硬编码数值不一致问题 3. 优化施法射程计算逻辑,复用HeroDisVal配置 4. 为敌人查找逻辑添加同路优先筛选逻辑 5. 修正部分英雄技能的弹道类型为贝塞尔曲线 6. 移除冗余的射程常量定义,统一配置管理 --- assets/script/game/common/config/SkillSet.ts | 6 +-- assets/script/game/common/config/heroSet.ts | 6 +-- assets/script/game/hero/MonMoveComp.ts | 8 +-- assets/script/game/hero/MoveComp.ts | 8 +-- assets/script/game/hero/SCastSystem.ts | 53 ++++++++++++++++---- 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index 91e48ec8..adec2a7d 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -193,7 +193,7 @@ export const SkillSet: Record = { 6001: { uuid:6001,name:t("skill_name_6001"),sp_name:"atk",icon:"1026",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, - RType:RType.linear,EType:EType.collision,buffs:[],info:t("skill_info_6001", 1, 100), + RType:RType.bezier,EType:EType.collision,buffs:[],info:t("skill_info_6001", 1, 100), }, 6002: { uuid:6002,name:t("skill_name_6002"),sp_name:"ball_fire",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", @@ -208,7 +208,7 @@ export const SkillSet: Record = { 6004: { uuid:6004,name:t("skill_name_6004"),sp_name:"ball_zi",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote, - RType:RType.linear,EType:EType.collision,buffs:[],info:t("skill_info_6004", 1, 100), + RType:RType.bezier,EType:EType.collision,buffs:[],info:t("skill_info_6004", 1, 100), }, 6005: { uuid:6005,name:t("skill_name_6005"),sp_name:"arrow",icon:"1135",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", @@ -248,7 +248,7 @@ export const SkillSet: Record = { 6104: { uuid:6104,name:t("skill_name_6104"),sp_name:"arrow_big_yellow",icon:"1135",TGroup:TGroup.Enemy,readyAnm:"yellow",endAnm:"",act:"max", DTType:DTType.single,crt:20,ap:100,hit_count:6,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.remote, - RType:RType.linear,EType:EType.collision,buffs:[],info:t("skill_info_6104", 6, 100), + RType:RType.bezier,EType:EType.collision,buffs:[],info:t("skill_info_6104", 6, 100), }, 6105: { uuid:6105,name:t("skill_name_6105"),sp_name:"atk_fire",icon:"1173",TGroup:TGroup.Enemy,readyAnm:"blues",endAnm:"",act:"max", diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 4fab9240..09879f35 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -69,7 +69,7 @@ export const FormationPointX = { } as const; export const HeroDisVal: Record = { - [HType.Melee]: 720, + [HType.Melee]: 120, [HType.Mid]: 720, [HType.Long]: 720, } @@ -207,7 +207,7 @@ export const HeroInfo: Record = { 6001:{uuid:6001,name:t("mon_name_6001"),path:"mo1", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,hp:120,ap:12,speed:100, skills:{6001:{uuid:6001,lv:1,cd:0.65,ccd:0}},info:""}, 6002:{uuid:6002,name:t("mon_name_6002"),path:"mo3", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,hp:120,ap:12,speed:100, - skills:{6001:{uuid:6001,lv:1,cd:0.65,ccd:0},6004:{uuid:6004,lv:1,cd:10,ccd:0}},info:""}, + skills:{6001:{uuid:6001,lv:1,cd:0.65,ccd:0}},info:""}, 6003:{uuid:6003,name:t("mon_name_6003"),path:"mo4", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,hp:350,ap:30,speed:100, skills:{6001:{uuid:6001,lv:1,cd:2,ccd:0}},info:""}, // 4. 远程 @@ -217,7 +217,7 @@ export const HeroInfo: Record = { skills:{6001:{uuid:6203,lv:1,cd:1.5,ccd:0}},info:""}, // 6. 精英/BOSS型 6006:{uuid:6006,name:t("mon_name_6006"),path:"mo6", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,hp:1500,ap:20,speed:100, - skills:{6002:{uuid:6002,lv:1,cd:2,ccd:0},6004:{uuid:6004,lv:1,cd:10,ccd:0}},info:""}, + skills:{6002:{uuid:6002,lv:1,cd:2,ccd:0}},info:""}, //============== 亡灵系列 =============== // 近战型 6101:{uuid:6101,name:t("mon_name_6101"),path:"mud1", fac:FacSet.MON,cards_lv:1,lv:1,type:HType.Melee,hp:120,ap:12,speed:100, diff --git a/assets/script/game/hero/MonMoveComp.ts b/assets/script/game/hero/MonMoveComp.ts index 8a36334b..ba2ea111 100644 --- a/assets/script/game/hero/MonMoveComp.ts +++ b/assets/script/game/hero/MonMoveComp.ts @@ -30,10 +30,6 @@ export class MonMoveComp extends ecs.Comp { @ecs.register('MonMoveSystem') export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { - /** 近战判定射程 */ - private readonly meleeAttackRange = 250; - /** 远程判定射程 */ - private readonly longAttackRange = 600; /** 渲染层级重排节流,避免每帧排序 */ private readonly renderSortInterval = 0.05; private lastRenderSortAt = 0; @@ -128,8 +124,8 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda private isEnemyInAttackRange(model: HeroAttrsComp, selfX: number, enemyX: number): boolean { const dist = Math.abs(selfX - enemyX); const rangeType = model.type as HType.Melee | HType.Mid | HType.Long; - if (rangeType === HType.Melee) return dist <= this.meleeAttackRange; - return dist <= this.longAttackRange; + const attackRange = HeroDisVal[rangeType]; + return dist <= attackRange; } private processCombatLogic(e: ecs.Entity, move: MonMoveComp, view: HeroViewComp, model: HeroAttrsComp, enemy: HeroViewComp) { diff --git a/assets/script/game/hero/MoveComp.ts b/assets/script/game/hero/MoveComp.ts index 40085bf9..2635eebc 100644 --- a/assets/script/game/hero/MoveComp.ts +++ b/assets/script/game/hero/MoveComp.ts @@ -48,10 +48,6 @@ interface MoveFacConfig { @ecs.register('MoveSystem') export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { - /** 近战判定射程 */ - private readonly meleeAttackRange = 250; - /** 远程判定射程 */ - private readonly longAttackRange = 600; private readonly heroFrontAnchorX = -100; private readonly monFrontAnchorX = 0; /** 常规同阵营横向最小间距(英雄) */ @@ -166,8 +162,8 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate private isEnemyInAttackRange(model: HeroAttrsComp, selfX: number, enemyX: number): boolean { const dist = Math.abs(selfX - enemyX); const rangeType = model.type as HType.Melee | HType.Mid | HType.Long; - if (rangeType === HType.Melee) return dist <= this.meleeAttackRange; - return dist <= this.longAttackRange; + const attackRange = HeroDisVal[rangeType]; + return dist <= attackRange; } private processCombatLogic(e: ecs.Entity, move: MoveComp, view: HeroViewComp, model: HeroAttrsComp, enemy: HeroViewComp) { diff --git a/assets/script/game/hero/SCastSystem.ts b/assets/script/game/hero/SCastSystem.ts index 11ea3d10..b004d634 100644 --- a/assets/script/game/hero/SCastSystem.ts +++ b/assets/script/game/hero/SCastSystem.ts @@ -5,7 +5,7 @@ import { HeroViewComp } from "./HeroViewComp"; import { DTType, RType, SkillConfig, SkillKind, SkillSet, SkillUpList, TGroup } from "../common/config/SkillSet"; import { Skill } from "../skill/Skill"; import { smc } from "../common/SingletonModuleComp"; -import { HeroInfo, HType } from "../common/config/heroSet"; +import { HeroDisVal, HeroInfo, HType } from "../common/config/heroSet"; import { Attrs } from "../common/config/HeroAttrs"; import { BoxSet, FacSet, FightSet } from "../common/config/GameSet"; import { oops } from "db://oops-framework/core/Oops"; @@ -140,8 +140,6 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate } /** 空施法计划:用于“当前无可施法技能”时的统一返回 */ private readonly emptyCastPlan = { skillId: 0, skillLv: 1, isFriendly: false, targetPos: null as Vec3 | null, targetEids: [] as number[] }; - /** 近战英雄默认施法射程 */ - private readonly meleeCastRange = 64; /** 查询缓存:避免每帧重复创建 matcher */ private heroMatcher: ecs.IMatcher | null = null; @@ -543,12 +541,16 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate /** * 在施法距离内查找最近敌人。 * 用于单体技能与基础目标参考。 + * 考虑三路设计:同路(Y差较小)优先,如果同路没有目标再考虑跨路 */ private findNearestEnemyInRange(heroAttrs: HeroAttrsComp, heroView: HeroViewComp, maxRange: number): HeroViewComp | null { if (!heroView.node) return null; const currentX = heroView.node.position.x; + const currentY = heroView.node.position.y; let nearest: HeroViewComp | null = null; let minDist = Infinity; + let foundSameLane = false; + ecs.query(this.getHeroMatcher()).forEach(entity => { const attrs = entity.get(HeroAttrsComp); const view = entity.get(HeroViewComp); @@ -556,10 +558,26 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate if (attrs.fac === heroAttrs.fac) return; if (attrs.is_dead || attrs.is_reviving) return; if (this.isOutOfBattleBounds(view.node.position.x)) return; - const dist = Math.abs(currentX - view.node.position.x); - if (dist > maxRange) return; - if (dist >= minDist) return; - minDist = dist; + + 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 (foundSameLane && !isSameLane) return; + + // 如果当前是同路,且之前没找到同路,则强制替换(同路优先) + if (isSameLane && !foundSameLane) { + foundSameLane = true; + minDist = distX; + nearest = view; + return; + } + + // 同等路况下比较距离 + if (distX >= minDist) return; + minDist = distX; nearest = view; }); return nearest; @@ -568,13 +586,17 @@ 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; const currentX = heroView.node.position.x; + const currentY = heroView.node.position.y; const direction = nearestEnemy.node.position.x >= currentX ? 1 : -1; let frontEnemy: HeroViewComp | null = null; let edgeX = direction > 0 ? Infinity : -Infinity; + let foundSameLane = false; + ecs.query(this.getHeroMatcher()).forEach(entity => { const attrs = entity.get(HeroAttrsComp); const view = entity.get(HeroViewComp); @@ -583,8 +605,20 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate if (attrs.is_dead || attrs.is_reviving) return; const enemyX = view.node.position.x; if (this.isOutOfBattleBounds(enemyX)) return; + 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; + frontEnemy = view; + return; + } + if (direction > 0) { if (enemyX >= edgeX) return; edgeX = enemyX; @@ -618,9 +652,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate private resolveMaxCastRange(heroAttrs: HeroAttrsComp, type: HType): number { const cached = heroAttrs.getCachedMaxSkillDistance(); if (cached > 0) return cached; - if (type === HType.Long) return 720; - if (type === HType.Mid) return 360; - return this.meleeCastRange; + const rangeType = type as HType.Melee | HType.Mid | HType.Long; + return HeroDisVal[rangeType]; } /** 生成沿目标方向的施法目标坐标 */