From 965b04094d28c55b05968ba4452efc58a7cd2767 Mon Sep 17 00:00:00 2001 From: pan Date: Thu, 20 Aug 2026 17:19:24 +0800 Subject: [PATCH] =?UTF-8?q?refactor(rogue):=20=E8=B0=83=E6=95=B4Rogue?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E6=80=AA=E7=89=A9=E9=85=8D=E7=BD=AE=E4=B8=8E?= =?UTF-8?q?=E6=88=98=E6=96=97=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增怪物出生站位配置 2. 调整单场战斗怪物数量为3只,支持0~2个Boss组合 3. 更新配置校验与怪物生成逻辑 4. 修复英雄预设体的尺寸与位置偏移 --- assets/resources/game/heros/mb1.prefab | 16 ++--- assets/script/game/common/config/GameSet.ts | 5 ++ assets/script/game/map/RogueConfig.ts | 74 +++++++++++++-------- 3 files changed, 59 insertions(+), 36 deletions(-) diff --git a/assets/resources/game/heros/mb1.prefab b/assets/resources/game/heros/mb1.prefab index 8113fc07..629eff64 100644 --- a/assets/resources/game/heros/mb1.prefab +++ b/assets/resources/game/heros/mb1.prefab @@ -250,7 +250,7 @@ "_lpos": { "__type__": "cc.Vec3", "x": 0, - "y": -86.962, + "y": -40.433, "z": 0 }, "_lrot": { @@ -290,8 +290,8 @@ }, "_contentSize": { "__type__": "cc.Size", - "width": 384, - "height": 384 + "width": 191.9, + "height": 192 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -981,8 +981,8 @@ }, "_contentSize": { "__type__": "cc.Size", - "width": 150, - "height": 150 + "width": 80, + "height": 100 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -1090,12 +1090,12 @@ "_offset": { "__type__": "cc.Vec2", "x": 0, - "y": 75 + "y": 50 }, "_size": { "__type__": "cc.Size", - "width": 150, - "height": 150 + "width": 80, + "height": 100 }, "_id": "" }, diff --git a/assets/script/game/common/config/GameSet.ts b/assets/script/game/common/config/GameSet.ts index f4e1ccca..cd0a2411 100644 --- a/assets/script/game/common/config/GameSet.ts +++ b/assets/script/game/common/config/GameSet.ts @@ -27,6 +27,11 @@ export enum FightSet { HERO_ROW_FRONT_X = -200, // 前排(最靠右迎敌):坦克 / 战士 HERO_ROW_MID_X = -260, // 中排:刺客 / 射手 HERO_ROW_BACK_X = -320, // 后排(最靠左):法师 / 辅助 + + /** 怪物三排出生/编队基准 x(y 均为 BoxSet.GAME_LINE):前排迎敌、中排、后排靠右 */ + MON_ROW_FRONT_X = 200, // 前排(最靠左迎敌):近战 / 重型 / 近战Boss + MON_ROW_MID_X = 260, // 中排:远程 / 刺客 / 远程Boss + MON_ROW_BACK_X = 320, // 后排(最靠右):辅助 / 召唤师 WAVE_COIN_BASE = 7, // 回合金币基础奖励 WAVE_COIN_GROW = 2, // 回合金币递增值 WAVE_COIN_MAX = 17, // 回合金币最大基础奖励 diff --git a/assets/script/game/map/RogueConfig.ts b/assets/script/game/map/RogueConfig.ts index a7884f65..97c6dd6a 100644 --- a/assets/script/game/map/RogueConfig.ts +++ b/assets/script/game/map/RogueConfig.ts @@ -4,7 +4,7 @@ * * 游戏机制: * - 整局只有一场战斗:开局英雄三次三选一后自动开战。 - * - 怪物从 BossComboLibrary 按权重随机抽一组(1 Boss + 4 小怪), + * - 怪物从 BossComboLibrary 按权重随机抽一组(固定 3 只怪:0~2 Boss + 剩余小怪), * 战斗开始瞬间一次全量登场(X∈[100,320] 均匀铺开),双方立即互相攻击。 * - 怪物全灭 → 胜利结算;英雄全灭 → 失败结算;无回合递进、无分批刷怪。 * @@ -18,7 +18,7 @@ * Boss 基础面板固定为初始英雄 2 倍强度(BOSS_BASE_HP/BOSS_BASE_AP),与小怪共用同一套系数, * 场上 Boss 恰好为小怪 2 倍强度(如需额外压场可调 BOSS_HP_BONUS_MUL)。 * 小怪基础面板与 1 级英雄持平(近战镜像 hp300/ap22/cd1.8),默认系数校准为 - * 整场战斗(3 英雄 vs 4 小怪 + 1 Boss)双方对砍 ≈ WAVE_DURATION(30s)。 + * 整场战斗(3 英雄 vs 3 只怪)双方对砍 ≈ WAVE_DURATION(30s)。 * 手感微调只改 MON_HP_MUL / MON_AP_MUL / BOSS_HP_BONUS_MUL 三个系数即可。 */ @@ -31,9 +31,10 @@ import { FacSet } from "../common/config/GameSet"; /** 单场战斗时长基准(秒):供清屏速度评价(BattleBannerComp 清屏奖励)等使用 */ export const WAVE_DURATION = 30; -/** 怪物登场固定构成:1 个 Boss + 4 个小怪(一次全量登场,打完即整局结束) */ -export const BOSS_COUNT = 1; -export const MINION_COUNT = 4; +/** 怪物登场固定构成:单场战斗固定 3 只怪,Boss 数量由组合配置决定(0~2 个), + * 剩余位置由小怪填充。例如:3 小怪、1 Boss + 2 小怪、2 Boss + 1 小怪(最大难度) */ +export const BOSS_COUNT = 2; +export const MINION_COUNT = 3; /** 怪物血量可调系数:最终 hp = HeroInfo 基础hp × MON_HP_MUL。 * 2.6 = 校准后怪物总血量 / 3 英雄 30s 输出(≈30 DPS),双方对砍 ≈ 30s 分胜负 */ @@ -104,11 +105,13 @@ export interface BossComboMinionSlot { count: number; } -/** Boss 组合配置:一场战斗随机抽一组登场(1 Boss + minions 小怪) */ +/** Boss 组合配置:一场战斗随机抽一组登场(固定 3 只怪,Boss 数量由 bossCount 决定) */ export interface BossComboConfig { id: string; name: string; - /** 小怪构成(合计数量建议等于 MINION_COUNT,超出截断、不足自动补近战) */ + /** 本场 Boss 数量(0~2),剩余位置由小怪填充 */ + bossCount: number; + /** 小怪构成(合计数量建议等于 MINION_COUNT - bossCount,超出截断、不足自动补近战) */ minions: BossComboMinionSlot[]; /** Boss 技能池 id(引用 BossSkillPool,可选) */ boss_skill_pool?: string[]; @@ -118,37 +121,46 @@ export interface BossComboConfig { weight: number; } -/** Boss 组合库(硬编码):每场战斗按权重随机抽一组 */ +/** Boss 组合库(硬编码):每场战斗按权重随机抽一组,固定 3 只怪。 + * 组合类型: + * - 3 小怪(0 Boss):均衡难度 + * - 1 Boss + 2 小怪:标准难度 + * - 2 Boss + 1 小怪:最大难度 */ export const BossComboLibrary: Record = { + /** 3 小怪:均衡组合 */ rage_charge: { - id: "rage_charge", name: "狂暴冲锋组", weight: 10, - minions: [{ type: MonType.Melee, count: 3 }, { type: MonType.Heavy, count: 1 }], - boss_skill_pool: ["boss_rage"], + id: "rage_charge", name: "狂暴冲锋组", weight: 10, bossCount: 0, + minions: [{ type: MonType.Melee, count: 2 }, { type: MonType.Heavy, count: 1 }], }, iron_wall: { - id: "iron_wall", name: "铁壁推进组", weight: 8, - minions: [{ type: MonType.Heavy, count: 2 }, { type: MonType.Support, count: 1 }, { type: MonType.Long, count: 1 }], - boss_skill_pool: ["boss_iron"], + id: "iron_wall", name: "铁壁推进组", weight: 8, bossCount: 0, + minions: [{ type: MonType.Heavy, count: 2 }, { type: MonType.Support, count: 1 }], skill_pool: ["tough"], }, doom_ritual: { - id: "doom_ritual", name: "毁灭仪式组", weight: 6, - minions: [{ type: MonType.Summoner, count: 1 }, { type: MonType.Long, count: 2 }, { type: MonType.Support, count: 1 }], - boss_skill_pool: ["boss_doom"], + id: "doom_ritual", name: "毁灭仪式组", weight: 6, bossCount: 0, + minions: [{ type: MonType.Summoner, count: 1 }, { type: MonType.Long, count: 1 }, { type: MonType.Support, count: 1 }], skill_pool: ["warcry"], }, + /** 1 Boss + 2 小怪:标准难度 */ assassin_raid: { - id: "assassin_raid", name: "刺客突袭组", weight: 7, - minions: [{ type: MonType.Assassin, count: 2 }, { type: MonType.Melee, count: 2 }], + id: "assassin_raid", name: "刺客突袭组", weight: 7, bossCount: 1, + minions: [{ type: MonType.Assassin, count: 1 }, { type: MonType.Melee, count: 1 }], boss_skill_pool: ["boss_rage", "boss_doom"], skill_pool: ["berserk"], }, blood_legion: { - id: "blood_legion", name: "吸血军团组", weight: 5, - minions: [{ type: MonType.Melee, count: 2 }, { type: MonType.Long, count: 1 }, { type: MonType.Summoner, count: 1 }], + id: "blood_legion", name: "吸血军团组", weight: 5, bossCount: 1, + minions: [{ type: MonType.Melee, count: 1 }, { type: MonType.Long, count: 1 }], boss_skill_pool: ["boss_iron", "boss_doom"], skill_pool: ["leech"], }, + /** 2 Boss + 1 小怪:最大难度 */ + twin_boss: { + id: "twin_boss", name: "双王降临", weight: 3, bossCount: 2, + minions: [{ type: MonType.Support, count: 1 }], + boss_skill_pool: ["boss_rage", "boss_iron", "boss_doom"], + }, }; /** @@ -277,7 +289,7 @@ export const BossSkillPool: Record = { export function validateRogueConfig(): string[] { const errors: string[] = []; - // 1. 校验组合引用与数量 + // 1. 校验组合引用与数量(固定 3 只怪:bossCount + minionTotal 必须等于 MINION_COUNT) for (const id in BossComboLibrary) { const combo = BossComboLibrary[id]; let minionTotal = 0; @@ -287,8 +299,12 @@ export function validateRogueConfig(): string[] { errors.push(`组合 ${id} 引用的怪物类型 ${slot.type}(${MonTypeName[slot.type] || "?"}) 在 MonList 中无可用 uuid`); } } - if (minionTotal !== MINION_COUNT) { - errors.push(`组合 ${id} 小怪数量=${minionTotal} 与 MINION_COUNT=${MINION_COUNT} 不一致`); + const totalMon = combo.bossCount + minionTotal; + if (totalMon !== MINION_COUNT) { + errors.push(`组合 ${id} 总怪数=${totalMon}(bossCount=${combo.bossCount} + minions=${minionTotal})与 MINION_COUNT=${MINION_COUNT} 不一致`); + } + if (combo.bossCount < 0 || combo.bossCount > BOSS_COUNT) { + errors.push(`组合 ${id} bossCount=${combo.bossCount} 超出允许范围 [0, ${BOSS_COUNT}]`); } if (combo.skill_pool) { for (const skillId of combo.skill_pool) { @@ -371,7 +387,7 @@ export const TestModeConfig = { export class RogueSpawningEngine { /** - * 生成一场战斗的怪物列表:随机一组 Boss 组合(1 Boss + 4 小怪,属性走基础×系数)。 + * 生成一场战斗的怪物列表:随机一组 Boss 组合(固定 3 只怪,Boss 数量由 combo.bossCount 决定)。 * Boss 压队尾(登场时由 MissionMonComp 统一布位)。 * @returns 怪物列表(小怪在前、Boss 在尾) */ @@ -383,6 +399,7 @@ export class RogueSpawningEngine { const combo = pickBossCombo(); const monsters: GeneratedMonster[] = []; + const bossCount = combo ? Math.max(0, Math.min(combo.bossCount, BOSS_COUNT)) : 0; if (combo) { for (const slot of combo.minions) { @@ -391,13 +408,14 @@ export class RogueSpawningEngine { } } } - // 组合库为空或数量不足兜底:补近战小怪至 MINION_COUNT - while (monsters.length < MINION_COUNT) { + // 组合库为空或数量不足兜底:补近战小怪至 MINION_COUNT - bossCount + const minionTarget = MINION_COUNT - bossCount; + while (monsters.length < minionTarget) { monsters.push(this.makeMonster(MonType.Melee, monsters.length)); } // Boss 压队尾 - for (let i = 0; i < BOSS_COUNT; i++) { + for (let i = 0; i < bossCount; i++) { monsters.push(this.makeBoss()); }