feat(刷怪): 增加场上怪物数量上限控制机制

- 新增 `maxMonsterCount` 和 `resumeMonsterCount` 属性配置怪物数量阈值
- 添加 `stop_spawn_mon` 状态控制刷怪暂停与恢复
- 实现 `syncMonsterSpawnState` 方法周期性同步怪物数量并自动管理刷怪状态
- 在战斗准备时重置刷怪状态,确保每局开始时刷怪正常
This commit is contained in:
panw
2026-03-18 09:26:47 +08:00
parent 08af676c84
commit 941fb50ce2
2 changed files with 41 additions and 1 deletions

View File

@@ -8,7 +8,7 @@ import { GameEvent } from "../common/config/GameEvent";
import { HeroViewComp } from "../hero/HeroViewComp";
import { UIID } from "../common/config/GameUIConfig";
import { SkillView } from "../skill/SkillView";
import { FightSet } from "../common/config/GameSet";
import { FacSet, FightSet } from "../common/config/GameSet";
import { mLogger } from "../common/Logger";
import { Monster } from "../hero/Mon";
import { Skill } from "../skill/Skill";
@@ -25,6 +25,10 @@ export class MissionComp extends CCComp {
private debugMode: boolean = false;
@property({ tooltip: "是否显示战斗内存观测面板" })
private showMemoryPanel: boolean = true;
@property({ tooltip: "场上怪物上限" })
private maxMonsterCount: number = 15;
@property({ tooltip: "恢复刷怪阈值" })
private resumeMonsterCount: number = 10;
// VictoryComp:any = null;
// reward:number = 0;
@@ -64,8 +68,10 @@ export class MissionComp extends CCComp {
private heapTrendPerMinMB: number = 0;
private heapTrendTimer: number = 0;
private heapTrendBaseMB: number = -1;
private monsterCountSyncTimer: number = 0;
private readonly heroViewMatcher = ecs.allOf(HeroViewComp);
private readonly skillViewMatcher = ecs.allOf(SkillView);
private readonly heroAttrsMatcher = ecs.allOf(HeroAttrsComp);
// 记录已触发的特殊刷怪索引
@@ -81,6 +87,7 @@ export class MissionComp extends CCComp {
if(!smc.mission.play) return
if(smc.mission.pause) return
if(smc.mission.in_fight){
this.syncMonsterSpawnState(dt)
if(smc.mission.stop_mon_action) return
smc.vmdata.mission_data.fight_time+=dt
this.FightTime-=dt
@@ -190,9 +197,12 @@ export class MissionComp extends CCComp {
smc.mission.play = true;
smc.mission.pause = false;
smc.mission.stop_mon_action = false;
smc.mission.stop_spawn_mon = false;
smc.vmdata.mission_data.in_fight=false
smc.vmdata.mission_data.fight_time=0
smc.vmdata.mission_data.mon_num=0
smc.vmdata.mission_data.level=0
smc.vmdata.mission_data.mon_max = Math.max(1, Math.floor(this.maxMonsterCount))
this.FightTime=FightSet.FiIGHT_TIME
this.rewards=[] // 改为数组,用于存储掉落物品列表
this.revive_times = 1; // 每次任务开始重置复活次数
@@ -207,6 +217,7 @@ export class MissionComp extends CCComp {
this.heapTrendPerMinMB = 0;
this.heapTrendTimer = 0;
this.heapTrendBaseMB = -1;
this.monsterCountSyncTimer = 0;
// 重置全局属性加成和主角引用 (确保新一局数据干净)
// smc.role = null;
@@ -216,6 +227,33 @@ export class MissionComp extends CCComp {
// mLogger.log(this.debugMode, 'MissionComp', "局内数据初始化",smc.vmdata.mission_data)
}
private getMonsterThresholds(): { max: number; resume: number } {
const max = Math.max(1, Math.floor(this.maxMonsterCount));
const resume = Math.min(max - 1, Math.max(0, Math.floor(this.resumeMonsterCount)));
return { max, resume };
}
private syncMonsterSpawnState(dt: number) {
this.monsterCountSyncTimer += dt;
if (dt > 0 && this.monsterCountSyncTimer < 0.2) return;
this.monsterCountSyncTimer = 0;
let monsterCount = 0;
ecs.query(this.heroAttrsMatcher).forEach(entity => {
const attrs = entity.get(HeroAttrsComp);
if (!attrs || attrs.fac !== FacSet.MON || attrs.is_dead) return;
monsterCount += 1;
});
smc.vmdata.mission_data.mon_num = monsterCount;
const { max, resume } = this.getMonsterThresholds();
smc.vmdata.mission_data.mon_max = max;
const stopSpawn = !!smc.mission.stop_spawn_mon;
if (stopSpawn) {
if (monsterCount <= resume) smc.mission.stop_spawn_mon = false;
return;
}
if (monsterCount >= max) smc.mission.stop_spawn_mon = true;
}
private cleanComponents() {
// 优化销毁顺序直接销毁实体让ECS系统自动处理组件清理
// 这样可以避免在组件reset方法中访问已经被销毁的实体引用

View File

@@ -65,6 +65,7 @@ export class MissionMonCompComp extends CCComp {
fight_ready(){
// 仅重置“本组件”刷怪状态,不处理其他系统状态
smc.vmdata.mission_data.mon_num=0
smc.mission.stop_spawn_mon = false
this.globalSpawnOrder = 0
this.gameTime = 0
this.waveTimer = 0
@@ -81,6 +82,7 @@ export class MissionMonCompComp extends CCComp {
if(!smc.mission.play) return
if(smc.mission.pause) return
if(smc.mission.stop_mon_action) return;
if(smc.mission.stop_spawn_mon) return;
if(!smc.mission.in_fight) return;
// 计时推进:所有“按时间驱动”的曲线都依赖 gameTime