chore: 清理过期设计文档并新增刷怪心流改造方案
删除了英雄UI重构和技能模板重构的旧设计文档,新增刷怪节奏优化的完整实施计划文档,包含三个阶段的具体改造步骤、验证方案和执行约束。
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
# 技能配置重构实施计划
|
||||
|
||||
## 1. 探索阶段总结 (Current State Analysis)
|
||||
经过对代码库的探索,当前技能触发系统及相关配置状态如下:
|
||||
- `SkillSet.ts` 包含了所有技能的基座配置 `SkillConfig` 和技能字典 `SkillSet`。
|
||||
- `heroSet.ts` 中的 `HeroInfo` 存放英雄和怪物的配置,目前 `call`, `dead`, `fstart`, `fend` 被定义为 `number[]`,而 `atking` 和 `atked` 被定义为 `{s_uuid: number, t_num: number}[]`。
|
||||
- `HeroAttrsComp.ts` 内部存储了与配置一致的触发技能结构。
|
||||
- `SkillTriggerHelper.ts` 负责判定并向外派发 `GameEvent.TriggerSkill` 事件,由 `SCastSystem.ts` 监听并执行 `forceCastTriggerSkill`。
|
||||
- 目前 `SCastSystem.ts` 在收集技能目标和施放技能时,都是直接从 `SkillSet[s_uuid]` 读取 `config`,没有针对具体角色的差异化机制。
|
||||
|
||||
## 2. 拟议变更 (Proposed Changes)
|
||||
|
||||
### 2.1 修改 `SkillSet.ts`
|
||||
- **新增接口**:定义 `SkillOverrides` 接口,包含所有可被角色覆盖的技能参数(如 `TGroup`, `ap`, `hit_count`, `buffs` 等,全部为可选字段)。
|
||||
- **新增函数**:编写 `mergeSkillParams(config, overrides?)` 函数,将基座 `config` 和角色覆盖 `overrides` 进行合并,返回一个新的 `SkillConfig` 对象。
|
||||
|
||||
### 2.2 修改 `heroSet.ts`
|
||||
- **扩展接口**:
|
||||
- 在 `HSkillInfo` 接口中增加 `overrides?: SkillOverrides;`。
|
||||
- 将 `heroInfo` 接口中的触发字段 `call`, `dead`, `fstart`, `fend`, `atking`, `atked` 统一更新为 `{ s_uuid: number; t_num: number; overrides?: SkillOverrides }[]` 结构。
|
||||
- **更新配置示例**:按照设计文档更新英雄 `5001`, `5002`, `5301`, `5302` 的配置,为特定的触发技能添加 `overrides` 字段(如盾骑士 5002 全队护盾覆盖)。
|
||||
|
||||
### 2.3 修改 `HeroAttrsComp.ts`
|
||||
- **同步类型**:将 `call`, `dead`, `fstart`, `fend`, `atking`, `atked` 的类型同步改为与 `heroInfo` 一致的 `{ s_uuid: number; t_num: number; overrides?: SkillOverrides }[]`。
|
||||
|
||||
### 2.4 修改 `SkillTriggerHelper.ts`
|
||||
- **派发支持**:
|
||||
- 更新 `dispatchSingle` 方法签名,增加 `overrides?: SkillOverrides` 参数,并在 `oops.message.dispatchEvent(GameEvent.TriggerSkill, {...})` 中将其传入。
|
||||
- 更新 `handleCall`, `handleDead`, `handleArrayTrigger` 处理逻辑,将原先对 `number[]` 的处理改为对 `{s_uuid, t_num, overrides}` 对象数组的处理,并提取 `overrides` 传递给 `dispatchArray`。
|
||||
- 更新 `handleAtking`, `handleAtked` 中的 `dispatchSingle` 调用,传入 `atkConfig.overrides`。
|
||||
|
||||
### 2.5 修改 `SCastSystem.ts` (关键运行时逻辑)
|
||||
- **事件监听更新**:在 `onTriggerSkill` 方法的 `args` 参数定义中补充 `overrides?: SkillOverrides`,并传递给 `forceCastTriggerSkill`。
|
||||
- **合并逻辑上移(架构优化)**:
|
||||
- 在 `forceCastTriggerSkill` 和 `castSkill` 的**方法入口处**(而非 `applyFriendlySkillEffects` 内部),第一时间调用 `mergeSkillParams(config, overrides)` 获取 `effective` 技能配置。
|
||||
- 将后续所有关于阵营判定(如 `effective.TGroup`)、目标收集、以及传递给 `applyFriendlySkillEffects` / `applyEnemySkillEffects` 的参数全部替换为 `effective`。
|
||||
- **为何如此设计**:如果在原设计中仅在 `applyFriendlySkillEffects` 入口处合并,那么前置的**目标选择逻辑**(依赖 `TGroup` 判定是 `Self` 还是 `Team`)将会使用未合并的基础配置,导致类似“自己加盾变为全队加盾”的 `TGroup` 覆盖无法生效。将合并操作前置可以彻底解决这一问题。
|
||||
- **主动技能支持**:在 `pickCastSkill` 中,读取 `heroAttrs.skills[s_uuid]?.overrides` 并进行合并判定,同时将 `overrides` 放入返回的 `castPlan` 中,以便 `castSkill` 使用。
|
||||
|
||||
## 3. 假设与决策 (Assumptions & Decisions)
|
||||
- **统一触发结构**:虽然 `call`, `dead`, `fstart`, `fend` 不严格需要 `t_num`,但为了类型统一并完全遵守设计规范,统一采用了包含 `t_num` 的对象结构。
|
||||
- **合并前置决策**:如上所述,坚决在施放方法入口处进行 `mergeSkillParams` 以保证目标收集逻辑能够感知到 `TGroup` 的变化。这比设计规范中要求的修改范围略有扩大,但对于系统功能的正确实现是必须的。
|
||||
- **卡牌技能影响**:卡牌技能(`forceCastCardSkill`)当前没有绑定角色的 `overrides`,因此维持读取基础 `SkillSet` 逻辑不变。
|
||||
|
||||
## 4. 验证步骤 (Verification steps)
|
||||
1. 编译 TypeScript 代码,确保 `HeroAttrsComp`, `heroSet`, `SCastSystem` 等修改后的接口和类型无报错。
|
||||
2. 启动游戏或运行测试,确认 `5001` (见习战士) 触发的基础护盾只对自己生效。
|
||||
3. 确认 `5002` (盾骑士) 受击触发的护盾技能,正确地为全队附加护盾,并且护盾值(ap)与次数(hit_count)符合 `overrides` 配置。
|
||||
4. 确认所有旧版英雄技能在无 `overrides` 时能够正确回退到 `SkillSet` 的默认配置,游戏运转正常无异常日志。
|
||||
@@ -1,55 +0,0 @@
|
||||
# 重构场上英雄UI表现及交互计划
|
||||
|
||||
## 1. 目标与现状分析
|
||||
|
||||
**现状**:
|
||||
目前游戏中 `HInfoComp.ts` 负责在界面下方显示场上英雄的信息(生命、攻击、出售),由 `MissionCardComp` 管理 6 个固定槽位。
|
||||
`HeroViewComp.ts` 负责战斗场景中英雄实体的动画表现。
|
||||
|
||||
**目标**:
|
||||
1. 保留 `HInfoComp.ts` 组件及预制体,但**取消其在底部的常驻显示**,将其改造为**弹窗形式**(类似 `IBoxComp`)。
|
||||
2. 在战斗或准备阶段,玩家**直接点击场上的英雄模型**(`HeroViewComp`)时,弹出 `HInfoComp` 面板。
|
||||
3. 清理 `MissionCardComp.ts` 中管理底层 `HInfoComp` 的旧逻辑。
|
||||
|
||||
## 2. 具体修改步骤
|
||||
|
||||
### 2.1 注册 HInfo 为独立弹窗
|
||||
* 修改 `assets/script/game/common/config/GameUIConfig.ts`:
|
||||
* 在 `UIID` 枚举中添加 `HInfo`。
|
||||
* 在 `UIConfigData` 中注册:`[UIID.HInfo]: { layer: LayerType.UI, prefab: "gui/element/hnode" }`。
|
||||
|
||||
### 2.2 改造 HInfoComp.ts
|
||||
* **数据传入**:添加 `onAdded(args: { eid: number })`,根据 `eid` 查询 `HeroAttrsComp` 实体进行数据绑定。
|
||||
* **自驱动刷新**:原先由外部驱动刷新,现在添加 `update(dt: number)` 生命周期,在内部调用 `this.refresh()` 以保持血量等信息实时更新。
|
||||
* **移除旧逻辑**:删除 `node_index`、`refreshByNodeIndex` 等固定槽位相关的代码。
|
||||
* **交互恢复**:取消注释 `bindEvents` 和 `unbindEvents`,恢复出售按钮的点击事件。出售完成后调用 `oops.gui.remove(UIID.HInfo)`。打开 `IBox` 的点击逻辑可保持不变(或者作为详情按钮)。
|
||||
* **添加关闭机制**:考虑到它是弹窗,可以添加一个点击非按钮区域关闭自身的功能,或者点击英雄之外的区域关闭。为简单起见,可以暂时复用点击面板打开 IBox(同时关闭 HInfo),并在 HInfo 添加额外的关闭按钮,或由 UI 框架自动处理(如果注册为 PopUp 并带有背景)。如果它是纯 UI,可以点击其他地方关闭。这里我们让它在打开 `IBox` 后关闭自己:`oops.gui.remove(UIID.HInfo)`。
|
||||
|
||||
### 2.3 清理 MissionCardComp.ts
|
||||
* **移除属性**:删除 `@property(Node) hero_info_node` 和 `@property(Prefab) hero_info_prefab` 及其编辑器绑定。
|
||||
* **移除内部状态**:删除 `cachedHInfoComps` 和 `heroInfoSyncTimer`。
|
||||
* **移除生命周期调用**:在 `onLoad`、`update`、`onMissionStart`、`onMissionEnd`、`onDestroy`、`reset`、`enterPreparePhase`、`enterBattlePhase` 中,删除所有涉及 `HInfoComp` 实例创建、刷新、显隐控制、销毁的代码。
|
||||
|
||||
### 2.4 修改 HeroViewComp.ts 添加点击交互
|
||||
* **绑定事件**:在 `onLoad` 中为英雄模型节点绑定点击事件 `this.node.on(NodeEventType.TOUCH_END, this.onHeroClicked, this);`,并在 `reset` 等清理处解绑。
|
||||
* **点击回调逻辑**:
|
||||
```typescript
|
||||
private onHeroClicked(event: EventTouch) {
|
||||
if (!this.model) return;
|
||||
if (this.model.fac !== FacSet.HERO) return; // 仅对玩家英雄生效
|
||||
|
||||
const eid = this.ent?.eid;
|
||||
if (!eid) return;
|
||||
|
||||
// 呼出英雄信息弹窗
|
||||
oops.gui.remove(UIID.HInfo);
|
||||
oops.gui.open(UIID.HInfo, { eid: eid });
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 验证步骤
|
||||
1. 进入战斗,确认下方不再有常驻的英雄信息面板。
|
||||
2. 点击场上的英雄模型,确认能弹出该英雄的 `HInfoComp` 弹窗。
|
||||
3. 观察弹窗内的血量和攻击力是否能随战斗实时刷新。
|
||||
4. 点击弹窗上的出售按钮,确认英雄消失、金币增加且弹窗关闭。
|
||||
5. 点击弹窗上的信息区域,确认能弹出 `IBoxComp` 详情面板。
|
||||
247
.trae/documents/plan_spawn_flow_improvement.md
Normal file
247
.trae/documents/plan_spawn_flow_improvement.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# 刷怪心流改造 · 实施步骤与执行方案
|
||||
|
||||
> 基于对 RogueConfig.ts / MissionMonComp.ts / MissionComp.ts 的多 agent 调研与方案讨论产出。
|
||||
> 目标:让刷怪节奏产生"爽感"与心流(Flow),核心公式:**爽感 = 密度 × 可清性**,**心流 = 铺垫 → 峰值 → 释放循环 + 即时正反馈**。
|
||||
|
||||
---
|
||||
|
||||
## 阶段划分总览
|
||||
|
||||
```
|
||||
阶段一(P0 修复,4 项) → 安全网与曲线修正,不动体验结构
|
||||
阶段二(P1 节奏与 DDA,5 项) → 核心体验重塑,依赖链严格
|
||||
阶段三(P2-P3 反馈层,5 项) → 情绪反馈补全,可并行开发
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 阶段一:P0 修复
|
||||
|
||||
### Step 1.1 — P0-3 刷怪暂停死链路(先做:泄压阀)
|
||||
|
||||
**改动文件**:MissionMonComp.ts、MissionComp.ts
|
||||
|
||||
| # | 操作 | 位置 |
|
||||
|---|---|---|
|
||||
| 1 | `update()` 在 pending 统计之后、批次推进之前插入 `if (smc.mission.stop_spawn_mon) return;` | MissionMonComp L106 后 |
|
||||
| 2 | 阈值对齐:`maxMonsterCount` 80→60,`resumeMonsterCount` 45→40 | MissionComp L86-88 |
|
||||
| 3 | `changePhase(PrepareEnd)` 分支补 `smc.mission.stop_spawn_mon = false;`(防开局冻结 4 秒) | MissionComp L492-495 |
|
||||
|
||||
**验证**:临时 `maxMonsterCount=20` 进放松回合,确认到 20 只停刷、降 15 后续刷;wave 1 开局节奏无延迟。
|
||||
|
||||
**Commit**:`fix(mission): consume stop_spawn_mon in MissionMonComp update`
|
||||
|
||||
---
|
||||
|
||||
### Step 1.2 — P0-4 回合僵局超时(安全网)
|
||||
|
||||
**改动文件**:RogueConfig.ts、MissionComp.ts
|
||||
|
||||
| # | 操作 | 位置 |
|
||||
|---|---|---|
|
||||
| 1 | 新增常量 `WAVE_TIMEOUT = 75`(含 JSDoc) | RogueConfig 节奏常量区 |
|
||||
| 2 | MissionComp 新增字段 `skipRemainScoreOnBattleEnd`,`data_init` 复位 | MissionComp 运行时状态区 + L774 |
|
||||
| 3 | Battle 阶段 update 追加超时检测 `if (this.clearTime >= timeout) this.onBattleTimeout();`(timeout 取 `isBossWave ? 90 : WAVE_TIMEOUT`) | MissionComp L245-251 |
|
||||
| 4 | 新增 `onBattleTimeout()`:先扣 `wave_remain_monsters` → 销毁全部 MON 实体 → `mon_num=0` → 走 `TimeUpAdvanceWave` / `open_Victory` | MissionComp 回合管理区 |
|
||||
| 5 | BattleEnd 的 `wave_remain_monsters += mon_num` 加防重判断 | MissionComp L522-523 |
|
||||
|
||||
**验证**:临时 `WAVE_TIMEOUT=8`,确认 8 秒准点收束、评分已扣、factor 放水;TestModeConfig 高血怪模拟僵局验证 75s 前不结束。
|
||||
|
||||
**Commit**:`feat(mission): add wave battle timeout fallback`
|
||||
|
||||
---
|
||||
|
||||
### Step 1.3 — P0-1 Wave 1 错位修正
|
||||
|
||||
**改动文件**:RogueConfig.ts(单文件)
|
||||
|
||||
| # | 操作 | 位置 |
|
||||
|---|---|---|
|
||||
| 1 | `getWaveType`:`wave % 5 === 1` → `wave % 5 === 4` | L80 |
|
||||
| 2 | 同步 4 处注释:WaveType 枚举注释(L37)、文件头节奏注释(L21-23)、WaveConfigs 表头注释(L329-332)、表内"放松回合"行内注释从 wave 6/11/16 搬到 4/9/14 | 见左 |
|
||||
|
||||
**验证**:`getWaveType(1..20)` 断言输出 `N N N R P` × 4 循环;实机确认 wave 1 = 18 只、wave 4 ≈ 40 只低强度。
|
||||
|
||||
**Commit**:`fix(rogue): move relax wave to pre-boss slot (wave%5==4)`
|
||||
|
||||
---
|
||||
|
||||
### Step 1.4 — P0-2 Boss 压轴 + 预警
|
||||
|
||||
**改动文件**:RogueConfig.ts、MissionComp.ts、GameEvent.ts
|
||||
|
||||
| # | 操作 | 位置 |
|
||||
|---|---|---|
|
||||
| 1 | `SquadLibrary` 新增 `boss_guard`(weight:0,1 重甲+2 近战) | RogueConfig L191-198 |
|
||||
| 2 | `GeneratedMonster` 增加可选字段 `isBossGuard?: boolean` | RogueConfig L426-450 |
|
||||
| 3 | `generateWave` 重构第 3/4/8 步:Boss 不 push 首位 → 小队拼装 → 护卫队 `makeBossGuards()` → Boss 压队尾 → 批次统一分配后强制 Boss+护卫 `batch = BATCH_COUNT-1`;`remaining` 改为 `-= 4` | RogueConfig L509-554 |
|
||||
| 4 | `makeBoss` 的 `spawnIndex:0, batch:0` 改为占位默认值+注释 | RogueConfig L660-687 |
|
||||
| 5 | GameEvent 新增 `BossWarning = "BossWarning"` | GameEvent.ts |
|
||||
| 6 | `changePhase(BattleStart)`:`if (this.isBossWave)` 派发 `BossWarning { wave, eta: 20 }` | MissionComp L497-500 |
|
||||
| 7 | MissionComp 从 RogueConfig 补导入 `BATCH_INTERVAL, BATCH_COUNT` | MissionComp L51 |
|
||||
|
||||
**验证**:wave 5 确认 0s/10s 两批纯杂兵、20s Boss 带 3 护卫进场、总怪数=21;`BossWarning` 仅在 5/10/15/20 派发。
|
||||
|
||||
**Commit**:`feat(rogue): spawn boss in final batch with guards and warning event`
|
||||
|
||||
---
|
||||
|
||||
## 阶段二:P1 节奏与 DDA(依赖链严格)
|
||||
|
||||
依赖链:**P1-5 → P1-1 → P1-2 + P1-3(同批)→ P1-4**
|
||||
|
||||
### Step 2.1 — P1-5 数值语义澄清(等价变换先行)
|
||||
|
||||
**改动文件**:RogueConfig.ts(单文件)
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | 删除第 5 步(乘 hp_mul/ap_mul),第 6 步改为拆分 `hpScale = targetPower × hp_mul / totalBasePower`、`apScale = targetPower × ap_mul / totalBasePower` |
|
||||
| 2 | 更新文件头公式注释(L12-16)与 `hp_mul/ap_mul` 字段注释 |
|
||||
| 3 | 17/18/19 启用 `power_adjust: 1.05 / 1.10 / 1.20` |
|
||||
| 4 | `validateRogueConfig` 增加 `power_adjust ∈ [0.8, 1.3]` 校验 |
|
||||
|
||||
**验证**:改造前后固定 heroPower 打桩,逐怪 hp/ap 断言相等(等价回归);17/18/19 总强度阶梯断言。
|
||||
|
||||
**Commit**:`refactor(rogue): unify hp/ap mul into power scaling formula`
|
||||
|
||||
---
|
||||
|
||||
### Step 2.2 — P1-1 批次递增 + 间隔参数化
|
||||
|
||||
**改动文件**:RogueConfig.ts、MissionMonComp.ts
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | 新增 `BATCH_RATIO = [0.25, 0.35, 0.40]`、`FINALE_SQUAD_COUNT = 2`、`SPAWN_INTERVAL_BY_TYPE`(Normal 0.18 / Pressure 0.25 / Relax 0.12) |
|
||||
| 2 | 批次分配从 `i % 3` 改为 `assignBatches()`:配额切分 + 第三批补 2 个最强小队(`pickStrongestSquad` 按 `calcHeroPower(样本)×count` 评分);放松回合跳过收尾加压;`totalCount` 预留收尾小队名额防 `slice` 截掉 |
|
||||
| 3 | MissionMonComp:`MON_SPAWN_INTERVAL` 静态常量改为实例字段 `spawnInterval`,`onPhasePrepareEnd` 按 `getWaveType(currentWave)` 查表;`releaseCurrentBatch` 末尾的 spawnTimer 初始化同步改 |
|
||||
|
||||
**与 P0-2 的合并点**:`assignBatches` 需保留"Boss+护卫强制最后一批"逻辑。
|
||||
|
||||
**验证**:debugMode 日志打印每批只数与最强小队 id;放松回合 54 只应 ~6.5s 倾泻完。
|
||||
|
||||
**Commit**:`feat(rogue): progressive batch ratio and per-type spawn interval`
|
||||
|
||||
---
|
||||
|
||||
### Step 2.3 — P1-2 + P1-3 清场加速与 DDA 重做(**必须同 commit**)
|
||||
|
||||
**改动文件**:RogueConfig.ts、MissionMonComp.ts、MissionComp.ts、GameSet.ts
|
||||
|
||||
P1-2 部分(MissionMonComp):
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | 新增状态:`batchReleasedCount`、`batchFastForwarded`、`aliveCheckTimer`、`waveEarlySkipTotal`(public 只读) |
|
||||
| 2 | `releaseCurrentBatch` 记录当批数量;update 中 0.2s 节流调 `checkBatchEarlyAdvance()` |
|
||||
| 3 | `checkBatchEarlyAdvance`:存活比例 ≤25% 且本批已放完 → `batchTimer += 2s`、`waveEarlySkipTotal += 2`(每批一次) |
|
||||
|
||||
P1-3 部分(RogueConfig + MissionComp + GameSet):
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | `DynamicTuner` 重写:连续映射 `desired = 1 + (0.8 - clearTime/30) × 0.5`(死亡锚定 0.8)、滞回 2 回合、指数靠拢 50%、区间 [0.7, 1.3]、新增 `streak` 字段 |
|
||||
| 2 | MissionComp BattleEnd:`effectiveClearTime = clearTime + MonComp.waveEarlySkipTotal` 后传入 adjust;顺手写入 `lastWaveDeathCount`/`lastWaveClearTime` 快照(供 Step 2.4) |
|
||||
| 3 | `FightSet.WAVE_HEAL_RATE` 0.5→0.4;修正 MissionComp L676"恢复70%"幽灵注释 |
|
||||
|
||||
**验证**:脚本模拟三种 clearTime 曲线(恒 12s / 恒 25s / 交替)打印 20 回合 factor 轨迹;强 build 单回合时长应从 ~30s 压到 ~24-26s。
|
||||
|
||||
**Commit**:`feat(rogue): early batch advance and continuous DDA with hysteresis`
|
||||
|
||||
---
|
||||
|
||||
### Step 2.4 — P1-4 动态回合倒计时
|
||||
|
||||
**改动文件**:MissionComp.ts(单文件)
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | 新增档位常量 `COUNTDOWN_FAST=2.5 / NORMAL=4.0 / FULL=5.0`,删除/降级 `WAVE_COUNTDOWN_DURATION` |
|
||||
| 2 | `startWaveCountdown` 改调 `computeCountdown()`:有死亡→5s,clearTime<65%→2.5s,否则 4s(读 Step 2.3 写入的快照字段) |
|
||||
|
||||
**验证**:快清场回合倒计时显示 3→2→1;有死亡回合给满 5s。
|
||||
|
||||
**Commit**:`feat(mission): adaptive wave countdown based on last wave performance`
|
||||
|
||||
---
|
||||
|
||||
## 阶段三:P2-P3 反馈层
|
||||
|
||||
### Step 3.1 — 事件与工具基建 + P2-2 清屏庆祝 + P2-3 Boss 演出
|
||||
|
||||
**改动文件**:GameEvent.ts、MissionComp.ts、MissionMonComp.ts、**新增** ScreenShake.ts、**新增** BattleBannerComp.ts、mission.prefab(编辑器)
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | GameEvent 新增:`WaveClear` / `BossWarning`(Step 1.4 已加则跳过)/ `BossSpawn` / `CoinFly` / `ComboReach`,启用 `MonDead` |
|
||||
| 2 | 新增 `ScreenShake` 静态工具(抖 `smc.map.MapView.node`,强度/时长参数,收敛回原位) |
|
||||
| 3 | 新增 `BattleBannerComp`:统一横幅通道(右进 backOut → 停留 → 左出 backIn),监听 WaveClear/BossWarning/ComboReach,0.3s 去抖 |
|
||||
| 4 | MissionComp 清屏分支 dispatch `WaveClear { wave, clearTime, allAlive, fastClear }`(通关分支不派发) |
|
||||
| 5 | MissionMonComp `addMonsterAtGrid` isBoss 分支 dispatch `BossSpawn { pos }` |
|
||||
| 6 | 奖励规则:fastClear=1 → +2 金,=2 → +5 金,allAlive → +1 刷新石(走 MissionEconomy) |
|
||||
| 7 | **编辑器操作**:mission.prefab 新增 `banner` 节点(Label+背景),挂 BattleBannerComp |
|
||||
|
||||
**Commit**:`feat(battle): wave clear banner, boss warning and screen shake`
|
||||
|
||||
---
|
||||
|
||||
### Step 3.2 — P2-1 波次 HUD + P2-4 金币飞行
|
||||
|
||||
**改动文件**:**新增** WaveHudComp.ts、**新增** CoinFlyComp.ts、HeroAtkSystem.ts、mission.prefab(编辑器)
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | `WaveHudComp`:监听 NewWave 缓存 total;0.2s 轮询 `mon_num + pending_mon_num` 刷新进度条;静态生成 20 格旗帜(`getWaveType(i)===Pressure` 置 Boss 帧),当前回合脉动 |
|
||||
| 2 | HeroAtkSystem `scheduleDrop` 后 dispatch `CoinFly { worldPos, gold, isBoss }`;`onDeath` MON 分支 dispatch `MonDead` |
|
||||
| 3 | `CoinFlyComp`:独立 NodePool(上限 30),3-5 枚(Boss 8 枚)金币抛物线散开→加速飞向钱包;金币帧运行时取编辑器绑定的 `coinIconSrc.spriteFrame`;**账务立即结算、飞行纯表现** |
|
||||
| 4 | **编辑器操作**:prefab 新增 `wave_hud`(wave_lab/remain_lab/progress/flags)与 `fly_layer`(最高 sibling),挂组件并拖绑定 |
|
||||
|
||||
**Commit**:`feat(battle): wave progress HUD and coin fly animation`
|
||||
|
||||
---
|
||||
|
||||
### Step 3.3 — P3-1 连杀 Combo
|
||||
|
||||
**改动文件**:**新增** ComboComp.ts、mission.prefab(编辑器)
|
||||
|
||||
| # | 操作 |
|
||||
|---|---|
|
||||
| 1 | `ComboComp`:监听 MonDead,2s 滑动窗口计数,5/10/20 阈值派发 `ComboReach { count, tier }`;MissionEnd 清零 |
|
||||
| 2 | BattleBannerComp 消费 ComboReach:分级文案/颜色/震屏(tier2 `shake(8,0.3)`)+ 金币爆发 2/5/10 |
|
||||
| 3 | **编辑器操作**:prefab 挂 ComboComp |
|
||||
|
||||
**Commit**:`feat(battle): kill combo system with tiered rewards`
|
||||
|
||||
---
|
||||
|
||||
## 执行约束
|
||||
|
||||
**每次 commit 前必做**:
|
||||
1. `validateRogueConfig()` 返回空数组
|
||||
2. GetDiagnostics 检查改动文件无 TS 错误
|
||||
3. 手动验证项按各 Step 的验证清单执行
|
||||
|
||||
**Commit message** 遵循项目规范(Conventional Commits、英文、祈使句、≤50 字符)。
|
||||
|
||||
**资源依赖**(不阻塞开发,可后期补):Boss 旗帜帧 ×1、清屏/Boss 预警/连杀音效 ×5、金币入袋音效 ×1——占位方案:flash/dun/Hit/Critical/Fire/button 复用。
|
||||
|
||||
**风险最高的两步**:Step 1.1(PrepareEnd 时序坑)和 Step 2.3(P1-2/P1-3 必须同批)。实施时优先单独验证这两点。
|
||||
|
||||
---
|
||||
|
||||
## 附录:关键数值速查
|
||||
|
||||
| 参数 | 现值 | 目标值 | 所属 Step |
|
||||
|---|---|---|---|
|
||||
| getWaveType Relax 位 | wave%5==1 | wave%5==4 | 1.3 |
|
||||
| Boss 批次 | batch 0 | batch 2 + 3 护卫 | 1.4 |
|
||||
| maxMonsterCount / resume | 80 / 45 | 60 / 40 | 1.1 |
|
||||
| WAVE_TIMEOUT | 无 | 75s(Boss 90s) | 1.2 |
|
||||
| BATCH_RATIO | 33/33/33 | 25/35/40 + 收尾小队×2 | 2.2 |
|
||||
| 刷怪间隔 | 0.3s 统一 | Normal 0.18 / Pressure 0.25 / Relax 0.12 | 2.2 |
|
||||
| 清场加速 | 无 | 存活≤25% 时 batchTimer += 2s | 2.3 |
|
||||
| DynamicTuner | ±0.05 步进 [0.5, 2.0] | 连续映射+滞回 [0.7, 1.3] | 2.3 |
|
||||
| WAVE_HEAL_RATE | 0.5 | 0.4 | 2.3 |
|
||||
| 回合间倒计时 | 固定 5s | 2.5 / 4 / 5 三档 | 2.4 |
|
||||
| power_adjust 17/18/19 | 未使用 | 1.05 / 1.10 / 1.20 | 2.1 |
|
||||
Reference in New Issue
Block a user