refactor(monster): 重构移动组件体系,统一英雄与怪物移动逻辑

1. 删除废弃的 MonMoveComp,将功能合并到 MoveComp 中
2. 移除 MissionComp 中冗余的怪物最大数量配置计算
3. 优化英雄站位分配逻辑,近战优先靠前站位
4. 统一移动系统的边界约束与渲染排序逻辑
5. 清理 Hero.ts 中未使用的导入项
This commit is contained in:
pan
2026-08-13 09:20:27 +08:00
parent c27c81cfa6
commit 038abdc5d2
8 changed files with 102 additions and 613 deletions

View File

@@ -805,7 +805,6 @@ export class MissionComp extends CCComp {
this.clearTime = 0
smc.vmdata.mission_data.mon_num = 0
smc.vmdata.mission_data.level = 1
smc.vmdata.mission_data.mon_max = Math.max(1, Math.floor(this.maxMonsterCount))
this.currentPhase = MissionPhase.None;
this.currentWave = 1;
this.isBossWave = false;

View File

@@ -53,19 +53,20 @@ const { ccclass } = _decorator;
export class MissionHeroComp extends CCComp {
// ======================== 常量 ========================
/** 硬编码的英雄占位点(数量对齐 FightSet.HERO_MAX_NUM落点 X 统一,英雄落地后由 MoveComp 自行移位到阵型目标) */
public static readonly HERO_POSITIONS: Vec3[] = [
v3(-300, BoxSet.GAME_LINE, 0), // index 0
v3(-300, BoxSet.GAME_LINE, 0), // index 1
v3(-300, BoxSet.GAME_LINE, 0), // index 2
v3(-300, BoxSet.GAME_LINE, 0), // index 3
v3(-300, BoxSet.GAME_LINE, 0), // index 4
v3(-300, BoxSet.GAME_LINE, 0), // index 5
v3(-300, BoxSet.GAME_LINE, 0), // index 6
v3(-300, BoxSet.GAME_LINE, 0), // index 7
v3(-300, BoxSet.GAME_LINE, 0), // index 8
v3(-300, BoxSet.GAME_LINE, 0), // index 9
];
/**
* 英雄登场占位点:
* - 从 x=-300 开始,每个点位间隔 60x 向右递增表示更靠前)。
* - 分配规则:近战优先靠前(靠近 0 的高索引),远程/中程优先靠后(低索引)。
*/
public static readonly HERO_POSITIONS: Vec3[] = (() => {
const startX = -300;
const step = 60;
const positions: Vec3[] = [];
for (let i = 0; i < FightSet.HERO_MAX_NUM; i++) {
positions.push(v3(startX + i * step, BoxSet.GAME_LINE, 0));
}
return positions;
})();
/** 英雄出生时的掉落高度(从空中落到地面的像素差) */
private static readonly HERO_DROP_HEIGHT = 260
@@ -203,7 +204,7 @@ export class MissionHeroComp extends CCComp {
* 动态分配英雄上场的位置
* @param excludeEids 排除计算的实体ID数组避免复活时把自己算成占据的位置
*/
private pickPositionIndexForHero(excludeEids: number[] = []): number {
private pickPositionIndexForHero(excludeEids: number[] = [], heroType: HType = HType.Melee): number {
const heroes = this.getAllHeroes().filter(h => {
const m = h.get(HeroAttrsComp);
return m && !m.is_dead && !excludeEids.includes(h.eid);
@@ -215,8 +216,10 @@ export class MissionHeroComp extends CCComp {
if (m && m.posIndex >= 0) occupied.add(m.posIndex);
}
// 按索引顺序填充空位0..9),全部落点相同,英雄落地后自行移位
const slotPriority = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// 近战优先靠前x 更大,索引更大);远程/中程优先靠后x 更小,索引更小)
const slotPriority = heroType === HType.Melee
? [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const idx of slotPriority) {
if (!occupied.has(idx) && MissionHeroComp.HERO_POSITIONS[idx]) {
return idx;
@@ -255,7 +258,7 @@ export class MissionHeroComp extends CCComp {
private spawnHeroAt(uuid: number, hero_lv: number, card_lv: number, posIndex: number) {
let hero = ecs.getEntity<Hero>(Hero);
let scale = 1
const finalPosIndex = posIndex >= 0 ? posIndex : this.pickPositionIndexForHero();
const finalPosIndex = posIndex >= 0 ? posIndex : this.pickPositionIndexForHero([], HeroInfo[uuid]?.type ?? HType.Melee);
// 兜底:索引越界或点位缺失时复用 index 0保证 landingPos 一定有效
const landingPos = MissionHeroComp.HERO_POSITIONS[finalPosIndex] ?? MissionHeroComp.HERO_POSITIONS[0];
let spawnPos: Vec3 = v3(landingPos.x, landingPos.y + MissionHeroComp.HERO_DROP_HEIGHT, 0);

View File

@@ -8,7 +8,7 @@
*
* 关键设计:
* - 5 只怪在 X∈[100,320] 内按登场序号均匀铺开Boss/小怪同时登场,玩家看清阵容后三选一。
* - 实际阵型与推进由 MonMoveComp 在战斗中向移动自然形成,不再使用固定网格点。
* - 实际推进由统一 MoveComp 在战斗中向敌人移动自然形成,不再使用固定网格点。
* - 槽位索引仅用于 monGrid 寻路与 SCastSystem 索敌定位。
*/
import { _decorator, v3, Vec3 } from "cc";
@@ -22,7 +22,7 @@ import { GameEvent } from "../common/config/GameEvent";
import { BoxSet } from "../common/config/GameSet";
import { spawningEngine, GeneratedMonster, TestModeConfig, BOSS_COUNT, MINION_COUNT } from "./RogueConfig";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
import { MonMoveComp } from "../hero/MonMoveComp";
import { MoveComp } from "../hero/MoveComp";
const { ccclass, property } = _decorator;
@@ -158,7 +158,7 @@ export class MissionMonCompComp extends CCComp {
oops.message.dispatchEvent(GameEvent.BossSpawn, { pos: spawnPos.clone() });
}
const move = mon.get(MonMoveComp);
const move = mon.get(MoveComp);
if (move) {
move.spawnOrder = this.globalSpawnOrder;
}