refactor(rogue): 调整Rogue模式怪物配置与战斗逻辑

1. 新增怪物出生站位配置
2. 调整单场战斗怪物数量为3只,支持0~2个Boss组合
3. 更新配置校验与怪物生成逻辑
4. 修复英雄预设体的尺寸与位置偏移
This commit is contained in:
pan
2026-08-20 17:19:24 +08:00
parent e18bcf2133
commit 965b04094d
3 changed files with 59 additions and 36 deletions

View File

@@ -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": ""
},

View File

@@ -27,6 +27,11 @@ export enum FightSet {
HERO_ROW_FRONT_X = -200, // 前排(最靠右迎敌):坦克 / 战士
HERO_ROW_MID_X = -260, // 中排:刺客 / 射手
HERO_ROW_BACK_X = -320, // 后排(最靠左):法师 / 辅助
/** 怪物三排出生/编队基准 xy 均为 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, // 回合金币最大基础奖励

View File

@@ -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<string, BossComboConfig> = {
/** 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<string, MonSkillSet> = {
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());
}