From afe659b0fcbe8ec41ab3cbe5fac72144e4ee47eb Mon Sep 17 00:00:00 2001 From: panw Date: Fri, 30 Jan 2026 16:51:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=88=B7=E6=80=AA):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E6=80=AA=E7=89=A9=E5=AE=9A=E6=97=B6=E5=88=B7?= =?UTF-8?q?=E6=80=AA=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 MissionComp 中添加特殊刷怪检查,根据时间表触发精英/Boss - MissionMonComp 监听刷怪事件,将特殊怪物插入队列头部优先生成 - 调整刷怪配置,移除随机刷怪中的精英/Boss,改为固定时间生成 - 降低同屏怪物数量,提高单体质量,优化游戏节奏 --- assets/script/game/map/MissionComp.ts | 24 +++++++++++- assets/script/game/map/MissionMonComp.ts | 26 +++++++++++++ assets/script/game/map/RogueConfig.ts | 48 +++++++++++++----------- 3 files changed, 75 insertions(+), 23 deletions(-) diff --git a/assets/script/game/map/MissionComp.ts b/assets/script/game/map/MissionComp.ts index b0b00a8c..30d65f3e 100644 --- a/assets/script/game/map/MissionComp.ts +++ b/assets/script/game/map/MissionComp.ts @@ -4,7 +4,7 @@ import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/modu import { smc } from "../common/SingletonModuleComp"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { HeroAttrsComp } from "../hero/HeroAttrsComp"; -import { MonsterCost, MonType, calculateMonsterGold, getLevelExp, calculateMonsterExp } from "./RogueConfig"; +import { MonsterCost, MonType, calculateMonsterGold, getLevelExp, calculateMonsterExp, SpecialMonsterSchedule } from "./RogueConfig"; import { GameEvent } from "../common/config/GameEvent"; import { HeroViewComp } from "../hero/HeroViewComp"; import { UIID } from "../common/config/GameUIConfig"; @@ -40,6 +40,10 @@ export class MissionComp extends CCComp { gold:0, diamond:0 } + + // 记录已触发的特殊刷怪索引 + private spawnedSpecialIndices: Set = new Set(); + onLoad(){ this.on(GameEvent.MissionStart,this.mission_start,this) this.on(GameEvent.MonDead,this.do_mon_dead,this) @@ -58,7 +62,24 @@ export class MissionComp extends CCComp { if(smc.mission.stop_mon_action) return smc.vmdata.mission_data.fight_time+=dt smc.vmdata.mission_data.time-=dt + + // 检查特殊刷怪时间 + this.checkSpecialSpawns(smc.vmdata.mission_data.fight_time); } + } + + private checkSpecialSpawns(fightTime: number) { + SpecialMonsterSchedule.forEach((item, index) => { + if (!this.spawnedSpecialIndices.has(index) && fightTime >= item.time) { + this.spawnedSpecialIndices.add(index); + console.log(`[MissionComp] 触发特殊刷怪: ${item.desc}`); + oops.message.dispatchEvent("SpawnSpecialMonster", { + uuid: item.uuid, + type: item.type, + level: item.level + }); + } + }); } // 升级奖励触发 @@ -249,6 +270,7 @@ do_ad(){ smc.vmdata.mission_data.time=15*60 this.rewards=[] // 改为数组,用于存储掉落物品列表 this.revive_times = 1; // 每次任务开始重置复活次数 + this.spawnedSpecialIndices.clear(); // 重置特殊刷怪记录 // 重置英雄数据,确保新一局是初始状态 smc.vmdata.hero = { diff --git a/assets/script/game/map/MissionMonComp.ts b/assets/script/game/map/MissionMonComp.ts index 0913a6e1..879e49a6 100644 --- a/assets/script/game/map/MissionMonComp.ts +++ b/assets/script/game/map/MissionMonComp.ts @@ -43,6 +43,32 @@ export class MissionMonCompComp extends CCComp { onLoad(){ this.on(GameEvent.FightReady,this.fight_ready,this) this.on(GameEvent.NewWave,this.fight_ready,this) + // 监听特殊刷怪事件 (精英/Boss) + this.on("SpawnSpecialMonster", this.onSpawnSpecialMonster, this); + } + + /** + * 处理特殊刷怪事件 + * @param event 事件名 + * @param args 参数 { uuid, type, level, position?, buffs? } + */ + private onSpawnSpecialMonster(event: string, args: any) { + if (!args) return; + console.log(`[MissionMonComp] 收到特殊刷怪指令:`, args); + + // 插入队列头部,优先生成 + this.MonQueue.unshift({ + uuid: args.uuid, + position: args.position !== undefined ? args.position : 2, // 默认中间 + type: args.type, + level: args.level, + buffs: args.buffs || [] + }); + + // 让刷怪计时器立即满足条件,以便尽快生成 + // 注意:不直接调用 spawnNextMonster 是为了保持 update 循环的一致性 + const config = getRogueConfig(); + this.spawnTimer = config.spawnInterval + 0.1; } /** 视图层逻辑代码分离演示 */ diff --git a/assets/script/game/map/RogueConfig.ts b/assets/script/game/map/RogueConfig.ts index 297755ac..db1b09b2 100644 --- a/assets/script/game/map/RogueConfig.ts +++ b/assets/script/game/map/RogueConfig.ts @@ -92,16 +92,25 @@ export interface IRogueGlobalConfig { * 默认配置 */ export const DefaultRogueConfig: IRogueGlobalConfig = { - maxMonsterCount: 10, // 默认同屏10只 (原25) - 追求极致质量 + maxMonsterCount: 5, // 默认同屏5只 - 降低数量,提高单体质量 spawnLogicInterval: 1.0, // 每秒计算一次 - spawnInterval: 2.5, // 队列出怪间隔2.5秒 (原1.2) - 降低频率适配总量 - baseBudget: 1.0, // 基础预算 (原2.5) - 降低产出适配总量 + spawnInterval: 2.0, // 队列出怪间隔 + baseBudget: 1.0, // 基础预算 timeDifficultyFactor: 0.5, // 每分钟增加50%预算 survivalHpThreshold: 0.4, // 40%血量触发保护 survivalBudgetMultiplier: 0.7, // 保护时预算打7折 - maxSpawnPerLogic: 2 // 单次最多生成2只 (原3) + maxSpawnPerLogic: 2 // 单次最多生成2只 }; +// 精英怪和Boss刷新时间配置 (时间单位: 秒) +export const SpecialMonsterSchedule = [ + { time: 60, uuid: 5601, type: MonType.ELITE, level: 5, desc: "1分钟: 精英自爆兵" }, + { time: 180, uuid: 5601, type: MonType.ELITE, level: 10, desc: "3分钟: 精英自爆兵" }, + { time: 300, uuid: 5701, type: MonType.BOSS, level: 15, desc: "5分钟: 兽人首领" }, + { time: 600, uuid: 5701, type: MonType.BOSS, level: 25, desc: "10分钟: 兽人首领" }, + { time: 900, uuid: 5701, type: MonType.BOSS, level: 30, desc: "15分钟: 最终Boss" } +]; + // 当前配置实例 let currentConfig: IRogueGlobalConfig = { ...DefaultRogueConfig }; @@ -157,16 +166,6 @@ export function calculateBudget(timeInSeconds: number, heroHpRatio: number = 1.0 export function generateMonstersFromBudget(timeInSeconds: number, heroHpRatio: number = 1.0): IMonsConfig[] { const config = getRogueConfig(); - // 15分钟后只生成Boss - if (timeInSeconds >= 15 * 60) { - return [{ - uuid: 5701, - type: MonType.BOSS, - level: Math.floor(timeInSeconds / 60), - position: 2 - }]; - } - const budget = calculateBudget(timeInSeconds, heroHpRatio); const weights = getSpawnWeights(timeInSeconds); const monsters: IMonsConfig[] = []; @@ -193,9 +192,9 @@ export function generateMonstersFromBudget(timeInSeconds: number, heroHpRatio: n if (currentBudget >= cost) { currentBudget -= cost; + // 随机刷怪只生成普通怪,精英和Boss由固定时间控制 let type = MonType.NORMAL; - if (uuid === 5701) type = MonType.BOSS; - else if (MonsterCost[uuid] >= 10) type = MonType.ELITE; + // 即使随机到了高Cost怪,在这里也只按普通怪处理,或者在配置中彻底移除高Cost怪 monsters.push({ uuid: uuid, @@ -217,6 +216,7 @@ export function generateMonstersFromBudget(timeInSeconds: number, heroHpRatio: n * @param stage 当前波次 * @param timeInSeconds 游戏进行时间(秒) * @returns 波次因子 (0-1之间,15分钟时达到最大) + * @returns 波次因子 (0-1之间,15分钟时达到最大) */ function calculateWaveFactor(stage: number, timeInSeconds: number = 0): number { const MAX_GAME_TIME = 15 * 60; // 15分钟 = 900秒 @@ -428,17 +428,21 @@ function getSpawnWeights(timeInSeconds: number): SpawnWeight[] { { uuid: 5301, weight: 30 } ]; } else if (minutes < 14) { - // 8-14min: 阵地博弈 - 40% 战士, 30% 刺客, 20% 攻城/治疗/精英 + // 8-14min: 阵地博弈 - 移除精英怪,只保留普通怪 return [ { uuid: 5201, weight: 40 }, { uuid: 5301, weight: 30 }, - { uuid: 5401, weight: 10 }, - { uuid: 5603, weight: 10 }, - { uuid: 5701, weight: 10 } + { uuid: 5401, weight: 15 }, + { uuid: 5603, weight: 15 } ]; } else { - // 15min: 剧情杀/决战 - 100% Boss - return [{ uuid: 5701, weight: 100 }]; + // 15min+: 混合兵种,Boss由固定时间控制 + return [ + { uuid: 5201, weight: 30 }, + { uuid: 5301, weight: 30 }, + { uuid: 5401, weight: 20 }, + { uuid: 5603, weight: 20 } + ]; } }