feat(flow): 停点前移批——LevelRunner 入口停点模式(opt-in defer+零RNG漂移)+关卡开局即出图选路+A 区进度条退役(转 C 区钱包行,底行 548)+GDD 四文件对齐三区+art-bible 连带+06 条目解决移除(用户拍板 2026-09-23,台账 142)
This commit is contained in:
1 parent
c22174274c
commit
8eddcdd5a7
19 files changed
+190
-208
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# 美术圣经(Art Bible)— Dungeon Sweeper
|
||||
|
||||
> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归台账 125);历次修订明细见文末版本历史(现行为 v2.0)
|
||||
> 项目:Dungeon Sweeper(扫雷 × 自动战斗 闯关 Roguelike)· 状态:**第 1–9 节定稿**(§6 环境/§7 UI/§8 资产规范/§9 参考与反参考已于 2026-09-23 v1.8 按 D1/D2/D4/D5 框架成文;D3=§5 角色已于 v1.6 落地、v1.7 抽离独立文档;框架 2026-09-22 用户拍板,原登记于中间产物修订指导,经裁决不入库,明细归台账 125);历次修订明细见文末版本历史(现行为 v2.1)
|
||||
>
|
||||
> **Art Director Sign-Off (AD-ART-BIBLE)**:历次批均 SKIPPED(v1.8 §6–9 补全亦 SKIPPED)— Lean/Solo mode(非 PHASE-GATE;§6–9 已成文,full 门禁签核时机待用户表态)
|
||||
> 风格基调(2026-09-10 用户定稿):地牢题材但**非暗黑风**——轻快明亮的幻想冒险风,全年龄;像素风;角色 2~3 头身
|
||||
@@ -332,7 +332,7 @@
|
||||
|
||||
## 6. 环境与场景(Environment & Scenes)
|
||||
|
||||
> 本节定格面之外的场景容器怎么画:战斗舞台背景、营地场景、三关图类型色板方向、关卡间下探过渡。格内画法归 §3.2,情绪与能量归 §2,换色模板归 §4.3;本节不新增信息通道、不承载玩法语义。屏级分区布局(四区)的裁决权归 battle.md,本节只定环境资产的视觉规格。
|
||||
> 本节定格面之外的场景容器怎么画:战斗舞台背景、营地场景、三关图类型色板方向、关卡间下探过渡。格内画法归 §3.2,情绪与能量归 §2,换色模板归 §4.3;本节不新增信息通道、不承载玩法语义。屏级分区布局(三区 B/C/D)的裁决权归 battle.md,本节只定环境资产的视觉规格。
|
||||
|
||||
### 6.1 战斗舞台背景(B 区环境)
|
||||
|
||||
@@ -381,7 +381,7 @@
|
||||
|
||||
### 7.3 布局栅格
|
||||
|
||||
- **结构**:双舞台四区(A 顶栏进度/B 战斗画面/C 数据框/D 棋盘)为结构冻结项,分区尺寸与像素级裁决归 battle.md(HUD框架承载 1280×800 基座锚点值,如扫雷图区 1036×476、结算明细带展开 84px)。
|
||||
- **结构**:双舞台三区(B 战斗画面/C 数据框/D 棋盘;字母保持不重编)为结构冻结项,分区尺寸与像素级裁决归 battle.md(HUD框架承载 1280×800 基座锚点值,如扫雷图区 1036×504、结算明细带展开 84px)。
|
||||
- **栅格口径(候选)**:面板间距/内边距按 4px 步进档(8/12/16/24 候选),全 UI 恒定;数据区直角细线不占圆角预算。终值归样张批。
|
||||
|
||||
### 7.4 字体与字号
|
||||
@@ -452,6 +452,7 @@
|
||||
|
||||
## 版本历史
|
||||
|
||||
- **v2.1(2026-09-23)停点前移批连带同步(批内代拍板②引用,worktree stoppoint-shift-20260923,台账 142)**:§6 开篇与 §7.2 结构行「双舞台四区」改「双舞台三区(B/C/D,字母保持不重编)」、扫雷图区锚点 1036×476→1036×504——战斗屏 A 区进度条随停点前移批退役(战后返回关卡画面,节点链进度由关卡画面选路覆盖层节点态承载),28px 纵向空间归 C/D 底行;裁决权与事实源归属 battle.md/HUD框架 不变,历次版本历史行不动。
|
||||
- **v2.0(2026-09-23)UI 章迁入批 + 画布定档 + 色板方向裁定(用户对 v1.8 代拍板四项逐条表态+五缺口给口径;worktree art-ch69-amend-20260923,台账 138)**:①**§3.3/§4.4 物理迁入 §7**(用户拍板:UI 具体选择须在 UI 章定义,三/四章只留简单定义与方向指导——v1.8 代拍板①「按引用整合」据此推翻):§3.3/§4.4 降为方向指导节(各留一段+指路),细则全文迁 **§7.1 形状语法细则/§7.2 UI 色板细则**;§7 重排号 7.1–7.5(原 7.4 组件库语义并入 7.1,零内容损失);§6.2/§7.3/§7.5 与清单引用随改。②**§8.2 画布基准暂定值**(用户缺口一裁定):主角人设原图=48×72、主角战斗状态图(侧向)=48×72〔v1.9 待决注记「主角立绘档空缺」收口〕、棋盘小人=32×32 二头身独立派生资产(允许更小;36px 板占比摩擦沿「独立小源档」路线样张批定终值)、敌种立绘三档 48/64/96=普通怪(小)/精英(中)/Boss(大)对应关系经确认保留候选;旧「像素基准 32px」通用候选退役;1920 档缩放策略与帧数规格维持待裁决,登记 06-待办清单(表现与支撑/HUD框架节新条目),样张批时提醒。③**§6.3 三关色板方向**(用户裁定):underdark 幽暗地域=**冷调幽暗**(灰白蓝主调+少量紫黑点缀,紫系取紫罗兰域 ≈256° 候选、禁入带 300°–345° 不变)、deep_underdark 灰矮人矿城=**灰黑主调+矿脉金属色点缀**(金属质感族冷银/铜灰候选,奖励金亮金禁上格底 §4.2 不变)——替换 v1.8 苔绿/冷灰岩方向草案。④**§9.1 扩池候选否决**(Forager/杀戮尖塔不入池且撤登记——用户裁定美术参考意义不足;代拍板④收口)。⑤命名规范草案获确认(代拍板②收口)。清单 §0 像素行与风格宪法表指向随批。
|
||||
- **v1.9(2026-09-23)§8.2 待决注记批**(侧会话用户指令「你在这里直接把这件事给做了吧」;worktree art-s82-note-20260923,台账 137):§8.2 增两条待决注记——①**36px 板 × 32px 源摩擦**:32px 源在 45px 格 1× 占 ≈71% 合规、在 36px 格 1× 占 ≈89% 超「≤0.75 格边」红线且禁非整数缩放回退,出路二选一(棋盘小人独立更小源档如 24px 级 vs 两种板各出一版),样张批随格边长终值一并裁决,裁决前棋盘小人源图不排产;②**主角立绘档空缺**:主角 B 区站桩立绘未单独立档(现行 48/64/96px 阶梯按敌种 archetype 写),随战斗一屏样张锁「角色剪影方向/战斗空间」时一并定。头注「现行为」随批 v1.9。
|
||||
- **v1.8(2026-09-23)§6–9 四章补全批(D 框架 D1/D2/D4/D5 落地,圣经全章成文;worktree art-ch6-9-20260923,台账 136)**:**§6 环境与场景**——6.1 战斗舞台背景(明亮地窟/低对比自然后退/明度恒定适用/`wall_ambient` 联动/紫赤仅 Boss 战)、6.2 营地场景(烛光黄×木色/三柜台一字排开/亮起走饱和不动明度/系统语义归元进度 GDD)、6.3 三关图类型色板候选(dungeon 暖石棕基准档/underdark 苔绿偏灰/deep_underdark 冷灰岩,方向候选归样张批重跑 §1.4 冻结,增「与五组微光互辨」抽测)、6.4 下探过渡(渐变取下一关槽值,只动色相饱和);**§7 UI 设计**——7.1 视觉基准(§3.3/§4.4 上位法**按引用整合**,D5 框架「迁入」不物理迁移——保持形状/色彩两章完整性,物理迁移待用户另有裁决)、7.2 布局栅格(四区结构事实源归 battle.md+4px 步进档候选)、7.3 字体字号(Kenney CC0/Fusion Pixel OFL 候选+整数倍缩放+下限 18/14/13 事实源 HUD框架+禁字重区分)、7.4 组件库三类容器语义+极性冗余、7.5 营地界面;**§8 资产与技术规范**——8.1 两档定案+格边长口径(锚点 45/36px 事实源 battle.md,扩板与 1920 档换算归表现批)、8.2 像素基准 32px 候选(active.md 58 条挂账清偿入章)+整数倍缩放纪律+1920 档适配策略候选+画布档位候选、8.3 导出 PNG/SpriteFrames+命名规范候选草案(对象键=数据表主键,图标键契约的文件侧延伸)、8.4 帧数规格候选档;**§9 参考与反参考**——9.1 正面三款取/弃表+扩池候选(Forager/杀戮尖塔)仅登记不入池、9.2 反面四条绑条款(Darkest Dungeon 压暗/Gungeon 粒子色相爆炸/Hades 特效密度/传统扫雷八色),反面图证待素材生成。**同步面**——头注状态行/Sign-Off 注记/参考池行、art-assets-checklist §0 像素尺寸行与参考图行及 §6 依赖链、04-美术音频方向.md 参考指引随批。**代拍板四项待追认**——①D5「迁入」按引用整合不物理迁移;②命名规范候选草案;③栅格/画布/帧数候选值系起草非裁决;④扩池候选两款不入池仅登记。
|
||||
|
||||
@@ -221,14 +221,6 @@
|
||||
|
||||
**状态**:方向观察待立项(2026-09-20 登记防散佚;立项前不展开设计)
|
||||
|
||||
#### Alpha 第一批:冒险开局停点前移——关卡画面常驻枢纽(节点图先于首战+进度条退场落地)
|
||||
|
||||
**现状**:用户 2026-09-23 反馈冒险入口流程倒置(进冒险直进战斗、战后才弹节点图)并拍目标形态——先见关卡画面选节点、再进战斗/商店/营地节点屏,战后返回关卡画面;同批两裁定——**战斗屏进度条退场**(节点链进度只留关卡画面,战斗屏目标形态 B/C/D 三区)、**A 区 LevelStripView 退役不迁移**(关卡画面不重新实现,由 RouteOverlay 升级常驻页面承接:节点态语义同族 UiKit token、同一 runner 只读数据出口,零独有资产流失)。方案要素已落籍 `docs/architecture/adr-0006-board-node2d-rendering.md` 与 `board-node2d-migration-plan.md` §1。执行面:①流程停点前移(LevelRunner 加停点模式——关卡开始不自动 `_enter_node`,改出图选路;RouteOverlay 开合时机改常驻:进关卡即开、战后返回即开)②LevelStripView 删除面(类本体、ui_assembler 组装行 :28、main.gd `strip_view` 引用 :52 等、ui_probe :77-78 构建检查与 :188 报告行两断言、battle.md A 区条款)③GDD 修订面三项(HUD框架 四区结构表、关卡节点地图 节点链常显条款、battle.md 像素布局表)④冒烟面(新停点行为断言+探针同步)。**随批三待裁决**:B/C/D 是否重新编字母、进度条腾出的 28px 纵向空间归属、关卡画面上节点链进度的具体呈现形态。
|
||||
|
||||
**归属**:Alpha 开工第一批;建议先于棋盘 Node2D Phase A 实施批开工(两者零硬依赖——先正流程后迁棋盘为最省路径;Phase A 方案已定稿随时可开工)
|
||||
|
||||
**状态**:已立项登记(2026-09-23 用户拍板),待点名开工
|
||||
|
||||
### 难度曲线与Boss
|
||||
|
||||
#### 调参批数值点评登记(八型批随批登记)
|
||||
|
||||
@@ -64,28 +64,29 @@
|
||||
|
||||
每个节点在关卡内领一个**节点编号**(本文含义:关卡内不重复的序号,用来当战斗的定位地址;数据键沿用切片字段 `node_depth`)。Boss 的编号恒为全图最大——"最深处的房间是关底"这条直感由此保留。单链特例:一张每步只有一条连线的图就是一条链,此时节点编号等于它前面走过的战斗场数。第一关行集就是单链特例,切片代码零改动运行;分支图行集随第二关内容批落地(见 P1)。
|
||||
|
||||
呈现侧口径(2026-09-17 用户拍板):节点图的画面表达走**方块地牢观感**——节点画成地牢房间的方块、连线画成通道——但逻辑拓扑就是本文的节点图,不产生任何额外选路或探索语义;视觉规格归 [HUD 框架](../表现与支撑/HUD框架.md)。
|
||||
呈现侧口径(2026-09-17 用户拍板):节点图的画面表达走**方块地牢观感**——节点画成地牢房间的方块、连线画成通道——但逻辑拓扑就是本文的节点图,不产生任何额外选路或探索语义。关卡画面本体即节点链进度的呈现载体(选路覆盖层的常驻形态,节点态直接读图:已过暗金 / 当前金 / 候选下一跳通道亮金 / Boss 旗朱描边),不另设进度条组件;视觉规格归 [HUD 框架](../表现与支撑/HUD框架.md)。
|
||||
|
||||
### 行进与选路:兑付后确认,选路就是行进
|
||||
|
||||
**结论**:关卡里没有一次自动前进——每一步都是玩家亲手走出来的。
|
||||
**结论**:关卡里没有一次自动前进——每一步都是玩家亲手走出来的。关卡画面(节点图,选路覆盖层的常驻形态)是单关内的常驻枢纽:关卡开始即呈现,此后每次兑付结束都回到它再选路。
|
||||
|
||||
行进的完整循环如下:
|
||||
|
||||
```
|
||||
到达节点 → 节点兑付(开战 / 发奖 / 回血)→ 兑付反馈呈现 → 玩家确认
|
||||
→ 看当前节点的连线指向的下一批节点(岔路选其一;只有一条路就是"继续")
|
||||
→ 到达下一节点……直到 Boss 分出胜负
|
||||
关卡开始 → 呈现节点图选路停点(关卡画面;入口不自动进入,第一次选路就是"出发")
|
||||
→ 玩家选一条连线 → 到达所选节点 → 节点兑付(开战 / 发奖 / 回血)
|
||||
→ 兑付反馈呈现 → 玩家确认 → 返回关卡画面(战后回图)
|
||||
→ 再选路……直到 Boss 分出胜负
|
||||
```
|
||||
|
||||
两条纪律:
|
||||
|
||||
| 纪律 | 内容 |
|
||||
|---|---|
|
||||
| 兑付后确认 | 到达节点立即兑付,不设"进入前确认"步;兑付反馈呈现完,玩家确认才继续。战斗节点的确认挂在战斗结算画面上,奖励/恢复节点挂在兑付反馈覆盖层上,商店节点挂在商店覆盖层的离开动作上——复用既有呈现位,零新增交互范式 |
|
||||
| 零自动推进 | 确认之后是选路口:岔路口玩家选一条连线,单链路口确认"继续"。选了才走;不选就停在原地 |
|
||||
| 兑付后确认 | 到达节点立即兑付,不设"进入前确认"步;兑付反馈呈现完,玩家确认才回图。战斗节点的确认挂在战斗结算画面上,奖励/恢复节点挂在兑付反馈覆盖层上,商店节点挂在商店覆盖层的离开动作上——复用既有呈现位,零新增交互范式 |
|
||||
| 零自动推进 | 确认之后回到关卡画面的选路口:岔路口玩家选一条连线,单链路口确认"继续"。选了才走;不选就停在图上 |
|
||||
|
||||
开始关卡后的第一次行进确认就是"出发"。Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选路——关卡已定局,后续流程归冒险结构。
|
||||
Boss 兑付(胜利或英雄死亡)触发关卡收束点,此后不再有选路——关卡已定局,后续流程归冒险结构。
|
||||
|
||||
### 节点兑付:把控制流移交给小循环
|
||||
|
||||
@@ -132,12 +133,12 @@
|
||||
| 上游 | [难度曲线与Boss](难度曲线与Boss.md) | 敌我数值曲线与遭遇投放节奏的调参所有权;本文零数值 |
|
||||
| 上游 | [数据配置](../表现与支撑/数据配置.md) | 商店表(商品行 / GP 掉落参数 / 价格参数)的承载与统一读取;商店覆盖层的商品与定价数据源 |
|
||||
| 下游 | [战斗结算](../战斗循环/战斗结算.md) | 两个调用入口的发起方:战斗发起组装(定位信息)、关卡收束(清库) |
|
||||
| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 节点图呈现(方块地牢观感)、当前位置与选路口、兑付反馈覆盖层的数据源 |
|
||||
| 下游 | [HUD 框架](../表现与支撑/HUD框架.md) | 节点图呈现(方块地牢观感;关卡画面节点态即节点链进度呈现载体)、当前位置与选路口、兑付反馈覆盖层的数据源 |
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
1. 从冒险结构接收开始关卡(关卡序号、当前生命、生效上限),加载本关节点图,玩家确认出发,行进自入口节点开始。
|
||||
2. 每节点兑付完成后玩家选路前进;岔路选一条、单链点继续;零自动推进。
|
||||
1. 从冒险结构接收开始关卡(关卡序号、当前生命、生效上限),加载本关节点图并呈现选路停点(关卡画面),玩家在图上选出第一跳,行进自所选节点开始(入口节点不自动进入)。
|
||||
2. 每节点兑付完成并确认后返回关卡画面,玩家再选路前进;岔路选一条、单链点继续;零自动推进。
|
||||
3. 战斗 / Boss 节点:组装关卡序号 + 节点编号,移交战斗结算开战;战斗结束向冒险结构上报战斗结果。
|
||||
4. 奖励节点:触发节点奖励兑付(切片期 = 直通合法空态);恢复节点:向冒险结构发治疗封顶回报;商店节点:打开商店覆盖层,购买即时生效,离开后兑付确认。
|
||||
5. Boss 战胜利或任意战斗倒下 = 关卡收束点:先调战斗结算的关卡收束清库,再宣布关卡结束。
|
||||
@@ -160,7 +161,7 @@
|
||||
## 验收标准
|
||||
|
||||
- 图合法:行集通过加载校验——节点编号关卡内唯一、入口唯一、Boss 为唯一终点、连线无环、所有节点沿连线可达 Boss;违规配置加载期致命。
|
||||
- 行进自主:从入口到 Boss 的每一次前进都由玩家选路发起;不存在任何自动推进路径;倒下时行进终止。
|
||||
- 行进自主:从入口到 Boss 的每一次前进都由玩家选路发起(含关卡开始后的第一跳——关卡开始停在图上,入口节点不自动进入);不存在任何自动推进路径;倒下时行进终止。
|
||||
- 兑付移交:每场开战调用携带(关卡序号 + 节点编号),与节点图上该节点位置一致;每场战斗结束恰一次战斗结果上报。
|
||||
- 兑付后确认:战斗节点的继续确认挂战斗结算画面,奖励/恢复挂兑付反馈覆盖层;到达与兑付之间无确认步。
|
||||
- 恢复兑付:治疗封顶回报载荷 = 该关恢复比例(读关卡配置行);满血回复 0 是合法状态(执行语义归冒险结构)。
|
||||
@@ -184,3 +185,4 @@
|
||||
| v1.0 | 2026-09-17 | **定稿**(逐问题拍板,全用户裁决):① 形态重开——用户拍板重开[05-不做清单](../../05-不做清单.md)「路径分支地图后置」裁定,定稿为**分支节点图**(分层节点图,杀戮尖塔 / 哥布林弹珠同构;方块地牢美术观感、逻辑为节点图),P0 图定稿 + 单链特例先行;② 节点类型定稿四类封闭枚举不扩类;③ 行进交互定稿全节点确认 + 兑付后确认、零自动推进;④ 遭遇构成收窄为编排面三条(战斗内部初始化全归战斗小循环),寻址定稿节点编号升级(`node_depth` 语义升级为关卡内唯一节点编号,表键与字段名零改动,单链零漂移);⑤ 节点奖励拍板为功能道具的正式渠道(内容归魔法道具内容重定批,切片期直通为合法空态);⑥ 「精英与 Boss 编码位」(同层多遭遇由节点编号消解,不设编码位)与「多敌数量的消费面」(关卡层零消费)两悬案收口,同场多敌种面拆归战斗侧;⑦ 切片行进代码对照的接口漂移清单登记 06 |
|
||||
| v1.0.1 | 2026-09-17 | **P1 分支节点图内容与实现批落地**(用户拍板任务批——切片代码 / 难度曲线与Boss v0.7 / registry / 06 待办同批):首张分支图 = 切片关卡 2「第二层 · 幽暗地域」行集落地(9 节点网状图:入口 0 → 中间三层 2/3/2 → Boss 8,真实岔路 4 处,奖励点 + 恢复点各 1,战斗节点 6 + Boss);行进器图版推进(`choices_presented` 选路态 + `pick_next_node`——零自动推进,战斗胜利不再自动推进、`continue_after_node` 泛化为兑付确认,06 接口漂移清单 ④⑤⑧ 清偿);图合法性校验落地 `LevelTable.validate`(单链与图同一套算法,L1 零迁移过校验,违规加载致命);节点图选路 UI(选路覆盖层整图自绘——房间方块 + 通道连线 + 当前/候选高亮,占位图形质量;顶栏图形态渲染行进序列 + 候选);首页"关卡 2 试玩"直入口(测试模式,≠ 两关序列生效)。本版本号只记实现批状态,图规则口径零改动 |
|
||||
| v1.1 | 2026-09-20 | **商店房扩类(GP+商店房批,用户拍板——与冒险结构 / 战斗结算 / 地图战斗资源 / 难度曲线与Boss / registry / 切片同批)**:① 节点封闭枚举四类→五类(+商店房);② 编排规则定稿——每关恰 1、关底 Boss 前一位必经位(哈迪斯式"决战前最后一个补给点"定位);必经位由冒烟断言承载、图合法性六检零新增;③ 兑付定稿——打开商店覆盖层、购买即时生效写统一冒险加算区(与关卡大奖励同账,归冒险结构)、离开后兑付确认;商店房不携带战斗行;④ 节点兑付表 / 纪律表 / 依赖表 / P0 闭环 / 验收标准 / P2「事件类节点候选」注记同步 |
|
||||
| v1.2 | 2026-09-23 | **停点前移批(冒险入口流程倒置修复,用户 2026-09-23 拍板;上位裁决 `docs/architecture/adr-0006-board-node2d-rendering.md` 与 `docs/architecture/board-node2d-migration-plan.md` §1,代码实装另批并行)**:① 行进循环改停点前移口径——关卡开始即呈现节点图选路停点(关卡画面 = 选路覆盖层常驻化,入口节点不自动进入,第一次选路就是"出发"),选路确认进节点,兑付确认后返回关卡画面再选路(战后回图);兑付后确认、零自动推进两条纪律语义不变,只改承载位;② 呈现侧口径补进度承载条款——关卡画面本体即节点链进度呈现载体(节点态直接读图:已过暗金 / 当前金 / 候选下一跳通道亮金 / Boss 旗朱描边),不另设进度条组件(战斗屏 A 区进度条随批退役);③ P0 闭环两条、依赖表 HUD 框架行、验收标准「行进自主」条同步。**批内代拍板三项待追认**:① B/C/D 字母保持不重编;② 28px 纵向空间划归 C/D 底行;③ 关卡画面进度呈现由选路覆盖层节点态承载(登记面见 HUD框架 v0.8) |
|
||||
@@ -219,7 +219,7 @@ GP(显示名「金币」)是冒险内的一次性属性提升货币:战斗
|
||||
## P0 最小闭环
|
||||
|
||||
1. 待机中开始新冒险:注入新主种子(恰一次)、生命账本置满、序列位置 = 第 1 关。
|
||||
2. 开始关卡:把关卡序号、当前生命、生效上限下放关卡节点地图,后者开始节点链行进。
|
||||
2. 开始关卡:把关卡序号、当前生命、生效上限下放关卡节点地图,后者加载节点图并停在入口选路停点(关卡画面),行进自玩家首次选路开始。
|
||||
3. 每场战斗结束:战斗结果上报到达,账本回写生命终值;上报为 0(倒下)直接走失败结算。
|
||||
4. 恢复点节点:治疗封顶回报到达,按比例回血并封顶。
|
||||
5. 关底 Boss 被击杀 = 收束点:关卡节点地图先调战斗结算清库,再向本文宣布关卡结束(通关)。
|
||||
@@ -285,3 +285,4 @@ GP(显示名「金币」)是冒险内的一次性属性提升货币:战斗
|
||||
| v0.6 | 2026-09-21 | **冒险结构实现批落地登记(切片 AdventureRunner + LevelRunner 账本外置 + AdventureTable 建表——与切片代码 / registry / 03 / 06 / roadmap 同批)**:本批只记实现批状态,正文规则口径零改动。落地面 = 三关正式序列生效(首页「开始冒险」)、接口契约四件套正式侧承载(开始关卡 start_level_external / 战斗结果上报共享账本直写 / 治疗封顶回报 apply_rest / 关卡结束 level_finished)、生命账本与 GP 冒险账本上交冒险结构层、大奖励非末关恰兑付一次(末关钥石照记)、冒险摘要五件事产出、主种子恰一次注入(registry rng_service new_adventure 调用权同批登记)、结算受理只算一次;06 待办「两关序列未生效」「切片行进代码与定稿的接口漂移」「冒险表未建表」三条随批解决移除。**规划书冲突按代码为准登记两处**:①大奖励 `_pending_next_level` 置位先于 emit(信号同步派发——处理器内立即确认需标记已就位);②放弃受理补 state=running 守卫(契约 7 结算受理只算一次的 abandoned 侧对齐) |
|
||||
| v0.7 | 2026-09-21 | **放弃入口界面呈现批(用户拍板「放弃接口也要有」——台账 119,推翻本文原「MVP 无界面入口、呈现后置」条款)**:① 放弃入口挂[关卡节点地图](关卡节点地图.md)选路覆盖层(选路停点 = 天然非战斗期;战斗中拒绝转为防御兜底分支——入口在战斗期不可达);② 入口只在冒险模式开放,单关测试直入口没有可放弃的冒险对象;③ 正文改现行口径(放弃节 / 验收标准放弃条),P1 后置表「放弃入口的界面呈现」随落地移除(同表「两关序列生效」系 v0.6 已落地漏收口,顺手同口径移除);④ 验收闸 = ui_probe 三断言(默认隐藏 / 冒险模式可见 / 首战中按下被拒 state 保持 running)+ 冒烟既有放弃两态 API 断言 |
|
||||
| v0.8 | 2026-09-23 | **单关测试直入口退役(用户拍板——唯一试玩入口 = 完整三关冒险)**:正文改现行口径两处(放弃节「按钮只在冒险模式开放」的理由从「单关直入口无冒险对象」改为「选路覆盖层只在冒险模式出现」;验收标准放弃条同步去单关直入口从句)——放弃语义对象(整局冒险)与拒绝分支零改动。版本历史行(v0.7)按 ADR 纪律不回改 |
|
||||
| v0.9 | 2026-09-23 | **停点前移批流程口径对齐(用户 2026-09-23 拍板冒险入口流程倒置修复——与 HUD框架 / 关卡节点地图 / battle.md / `docs/architecture/adr-0006-board-node2d-rendering.md` 同批)**:P0 闭环「开始关卡」条改新流程口径——关卡节点地图加载节点图后停在入口选路停点(关卡画面,选路覆盖层常驻形态),行进自玩家首次选路开始;通读复核其余章节——「通关自动进下一关」属关卡序列层语义(进入下一关后仍出图选路,零矛盾)、接口契约四件套、收束点先清库后宣布、放弃入口(选路停点 = 天然非战斗期)等既有裁决零改动。**批内代拍板三项待追认**(字母不重编 / 28px 归 C/D 底行 / 进度呈现由选路覆盖层节点态承载)不落本文修订面,登记见 HUD框架 v0.8 |
|
||||
@@ -18,7 +18,7 @@ HUD框架把各玩法系统产生的事实变成玩家看得见、点得动、
|
||||
|
||||
| 负责 | 说明 |
|
||||
|---|---|
|
||||
| 战斗屏四区布局 | 四区系统级契约与常驻组件呈现形态;棋盘格尺寸定值档与装板校验 |
|
||||
| 战斗屏三区布局 | 三区系统级契约与常驻组件呈现形态;棋盘格尺寸定值档与装板校验 |
|
||||
| 输入翻译 | 鼠标操作翻译成意图批次、一帧内整批提交;悬停预承诺与可挖域指示 |
|
||||
| 提示体系 | toast 轻提示与一次性提示;拒绝反馈的呈现映射 |
|
||||
| 模态覆盖层家族 | 图例面板、明细回看、胜负终局共用的层级纪律 |
|
||||
@@ -50,20 +50,19 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
|
||||
本章六节:前三节定画面的骨架与进出规则(屏、弹层、刷新),后三节定数据与资产怎么进来(载荷、占位、底线)。
|
||||
|
||||
### 战斗屏四区双舞台:挖掘与结算同屏不切场景
|
||||
### 战斗屏三区双舞台:挖掘与结算同屏不切场景
|
||||
|
||||
战斗屏是 MVP 唯一的玩法屏,采用"双舞台"布局——战斗画面与扫雷图两块区域同屏常驻、互不顶替:挖掘期敌人在上方待机可见,轮末结算在原地逐行展开,全程不切换场景。"扫雷的因"与"战斗的果"因此永远摆在一起,因果不需要玩家凭记忆拼接。
|
||||
|
||||
四区各管一块:
|
||||
三区各管一块:
|
||||
|
||||
| 区 | 位置与尺寸 | 管什么 |
|
||||
|---|---|---|
|
||||
| A 关卡进度条 | 全宽 28px 顶栏 | 节点链步进与当前位置 |
|
||||
| B 战斗画面 | 全宽 252px | 主角站桩立绘、敌人站桩立绘 ×1–3(**全站桩形态,2026-09-20 用户拍板:无框立绘+底座、状态小图标挂血条下,英雄卡/敌人卡退役**)、轮次阶段指示、结算明细带 |
|
||||
| C 角色信息 | 左下 240×520 | 生命 / 攻击 / 储备数据框、状态效果槽、小人立绘 |
|
||||
| D 扫雷图 | 中下约 1036×520(原右下面板删除后横向加宽) | 行动点条与按钮组、棋盘本体、toast 槽 |
|
||||
| C 角色信息 | 左下 240×548 | 生命 / 攻击 / 储备数据框、状态效果槽、小人立绘 |
|
||||
| D 扫雷图 | 中下约 1036×548(原右下面板删除后横向加宽) | 行动点条与按钮组、棋盘本体、toast 槽 |
|
||||
|
||||
分区尺寸与组件落位的像素级裁决归 [battle.md](../../../ux/battle.md);四区结构与双舞台常驻是结构冻结项,修订走文档修订而非调参。
|
||||
分区尺寸与组件落位的像素级裁决归 [battle.md](../../../ux/battle.md);三区结构与双舞台常驻是结构冻结项,修订走文档修订而非调参。节点链进度不在战斗屏呈现——它由关卡画面(选路覆盖层常驻形态)的节点态承载,见[关卡节点地图](../冒险循环/关卡节点地图.md)。
|
||||
|
||||
**结论**:棋盘格边长取两档定值——12×12 的板用 36px、10×10 的板用 45px([battle.md](../../../ux/battle.md) 拍板值);下式不推导这两档,只在装板时校验"定值塞得进扫雷图区",违例立即报错中止。
|
||||
|
||||
@@ -78,10 +77,10 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
|---|---|---|
|
||||
| N | 棋盘边长格数 | 10 或 12([棋盘生成](../排雷循环/棋盘生成.md)的两档尺寸) |
|
||||
| 定值档 | 12×12 → 36px;10×10 → 45px | 结构冻结 |
|
||||
| 棋盘区宽 / 高 | 扫雷图区基准尺寸 | 1280×800 下 1036 / 476(520 减行动点条 44) |
|
||||
| 棋盘区宽 / 高 | 扫雷图区基准尺寸 | 1280×800 下 1036 / 504(548 减行动点条 44) |
|
||||
| 边距 | 水平 / 垂直 | 各 16px |
|
||||
|
||||
1280×800 下实算:可用高度 460px,12×12 得 38 ≥ 36、10×10 得 46 ≥ 45,两档都通过。宽度向同理余量充裕(1036−16 远大于 12 格定值档所需)。棋盘数字直接显示排雷玩法给的真值——呈现层禁止自己算数字,这是"数据层从不说谎"在呈现侧的镜像。
|
||||
1280×800 下实算:可用高度 488px,12×12 得 40 ≥ 36、10×10 得 48 ≥ 45,两档都通过。宽度向同理余量充裕(1036−16 远大于 12 格定值档所需)。棋盘数字直接显示排雷玩法给的真值——呈现层禁止自己算数字,这是"数据层从不说谎"在呈现侧的镜像。
|
||||
|
||||
### 提示与弹层:轻提示随起随消、重弹层排队进出
|
||||
|
||||
@@ -158,7 +157,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| 上游 | [增益状态](../战斗循环/增益状态.md) | 状态投影经战斗结算呈现面取得,零直读 |
|
||||
| 上游 | [地图战斗资源](../战斗循环/地图战斗资源.md) | 已开格奖励身份投影(`query_identity` 只读回调,组合根注入)零直读 |
|
||||
| 上游 | [关卡节点地图](../冒险循环/关卡节点地图.md) | 节点链、当前节点、跨战斗生命携带的读数;胜利后推进 |
|
||||
| 下游 | [战斗表现](../战斗循环/战斗表现.md) | 交付四区布局、明细带呈现位、敌人呈现语义(站桩形态);它只叠加动画密度与演出 |
|
||||
| 下游 | [战斗表现](../战斗循环/战斗表现.md) | 交付三区布局、明细带呈现位、敌人呈现语义(站桩形态);它只叠加动画密度与演出 |
|
||||
| 下游 | [音频](音频.md) | 挂点事件源(明细行类型流、toast 触发);MVP 无音频 |
|
||||
| 下游 | [教学引导](教学引导.md) | toast 与图例面板两个承载位——教学内容装进这两个容器 |
|
||||
| 下游 | [设置与本地化](设置与本地化.md) | 中文字体随包、按钮宽度、术语表等契约的消费方 |
|
||||
@@ -170,7 +169,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| [排雷玩法](../排雷循环/排雷玩法.md) | 已开 / 未开格态一眼可辨;悬停预承诺与可挖域常驻指示;移动路径预览即合法性指示;每次拒绝可感知且棋盘面细因可区分;停手被改判可感知 |
|
||||
| [行动经济](../排雷循环/行动经济.md) | 行动点与储备常显;储备清零反馈;棋盘面与资源面拒绝可区分;刷新入口与代价可读 |
|
||||
| [战斗结算](../战斗循环/战斗结算.md) | 未生效类明细行(奖励未生效)的呈现;高光行强调 |
|
||||
| [关卡节点地图](../冒险循环/关卡节点地图.md) | 节点链进度常显(A 区顶栏:当前节点奖励金高亮、已过暗金、Boss 旗朱描边、候选下一跳亮金);选路覆盖层只读呈现(零自动推进停点语义) |
|
||||
| [关卡节点地图](../冒险循环/关卡节点地图.md) | 节点链进度呈现(关卡画面选路覆盖层节点态承载:暗金已过、金当前、候选下一跳通道亮金、Boss 旗朱描边);选路覆盖层只读呈现(零自动推进停点语义) |
|
||||
| [敌人系统](../战斗循环/敌人系统.md) | 意图线索映射成文且全局恒定;单位顺位与血条可读;敌方共享层数各卡同值 |
|
||||
| [增益状态](../战斗循环/增益状态.md) | 状态栏常显;无状态时整排槽隐藏;有利 / 有害极性呈现不看数值符号 |
|
||||
| [地图战斗资源](../战斗循环/地图战斗资源.md) | 已开格的奖励身份常读 |
|
||||
@@ -179,7 +178,7 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
|
||||
## P0 最小闭环
|
||||
|
||||
1. 进入战斗屏:四区同屏就绪,半秒内首格可点。
|
||||
1. 进入战斗屏:三区同屏就绪,半秒内首格可点。
|
||||
2. 挖掘期鼠标操作经单意图帧整批提交(唯一写路径,经组合根)。
|
||||
3. 回执链:组合根重查只读面,界面字段级就地刷新。
|
||||
4. 轮末进入结算:棋盘区锁输入,明细带展开逐行兑现(战斗结算流水驱动)。
|
||||
@@ -213,13 +212,13 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| reduce_motion_scale | 每段动画 | 0.5 或跳终态 | 减动效开关系数 |
|
||||
| detail_band_height | 结算明细带 | 24 / 84 px | 摘要 / 实时流两态高度 |
|
||||
|
||||
结构冻结(非调参项,改动走文档修订):四区布局与分区尺寸、双舞台常驻、单意图帧纪律、弹层层级纪律、图标键映射契约、程序化占位策略、订阅纪律。性能预算为引用值:同屏 draw calls < 200、进入战斗屏 500ms 内可交互。
|
||||
结构冻结(非调参项,改动走文档修订):三区布局与分区尺寸、双舞台常驻、单意图帧纪律、弹层层级纪律、图标键映射契约、程序化占位策略、订阅纪律。性能预算为引用值:同屏 draw calls < 200、进入战斗屏 500ms 内可交互。
|
||||
|
||||
## 验收标准
|
||||
|
||||
以下判据逐条可测,全部通过才算闭环达标。
|
||||
|
||||
- 四区无遮挡、无重叠、无内容裁切(棋盘全部格子与数字完整可见),分区尺寸与 battle.md 布局表一致;同屏 draw calls < 200;进入战斗屏 500ms 内首格可点。
|
||||
- 三区无遮挡、无重叠、无内容裁切(棋盘全部格子与数字完整可见),分区尺寸与 battle.md 布局表一致;同屏 draw calls < 200;进入战斗屏 500ms 内首格可点。
|
||||
- 两档板装板后格边长取定值档(36 / 45px)且可行性校验通过;数字字号不低于下限、整数倍缩放无模糊。
|
||||
- 已开 / 未开格态在灰度截图下可逐格分类;已引爆雷格"可通行可读"(已开底加巢穴纹、可作移动目标)。
|
||||
- 悬停光标三语义(移动 / 挖 / 旗)随目标切换并高亮目标格;悬停已开格画出合法路径(不可达不显示);可挖域常驻呼吸微光。
|
||||
@@ -251,3 +250,4 @@ HUD框架站在玩家与全部玩法系统之间:挖掘期它是输入的翻
|
||||
| v0.5 | 2026-09-17 | 数值纪律收口批:调参表标注文档自持口径(无表承载常量的唯一事实源声明) |
|
||||
| v0.6 | 2026-09-20 | **敌人卡形态裁决收口批(与 battle.md / 战斗表现 / 06 清单同批,台账 99)**:全站桩形态拍板——B 区主角与敌人均为无框立绘+底座、状态小图标挂血条正下方,英雄卡/敌人卡退役;B 区行、敌人呈现义务行(载体由卡改立绘,意图占位/共享层数各立绘同值/死亡灰化退场等义务面平移)、下游战斗表现交付行、就地更新示例措辞四处同步;攻击值等规划数据仍归 C 区数据框(C 区不动)。呈现快照数据面零改动(消费字段不变,只换呈现载体) |
|
||||
| v0.7 | 2026-09-20 | **表现层三批落地 + 义务清单补行(代码同日三批:样式收敛 / 站桩改造 / 结算演出链)**:呈现义务来源清单补「关卡节点地图」行(节点链进度常显 + 选路覆盖层只读呈现——此前漏登记);新增结算演出覆盖层(跨区弹道/光带载体,兑现演出因果可视);减动效承诺落地(UiKit.motion 单点包装全部呈现层 tween 时长,开启时长减半、可挖域呼吸停格;切片期入口 = TunePanel 开关,正式设置层归设置批)。代码侧站桩载体(StandeeView)与卡片退役随 v0.6 裁决执行 |
|
||||
| v0.8 | 2026-09-23 | **停点前移批(冒险入口流程倒置修复,用户 2026-09-23 拍板;上位裁决 `docs/architecture/adr-0006-board-node2d-rendering.md` 与 `docs/architecture/board-node2d-migration-plan.md` §1,代码实装另批并行)**:① 战斗屏布局四区 → 三区——删 A 区关卡进度条行(LevelStripView 退役删除,节点链进度呈现移出战斗屏、只留关卡画面);C/D 区纵向 520 → 548;装板校验变量与实算同步(棋盘区高 504、可用高度 488);② 呈现义务来源清单「关卡节点地图」行改承载口径——节点链进度由关卡画面选路覆盖层节点态承载(暗金已过 / 金当前 / 候选下一跳通道亮金 / Boss 旗朱描边),不另设进度条组件;③ 「四区」措辞全线改「三区」(负责表、节题、结构冻结、验收、下游战斗表现交付行),双舞台常驻语义不动。**批内代拍板三项待追认**:① B/C/D 字母保持不重编(字母是跨文档/代码注释的承载标识);② A 区 28px 纵向空间划归 C/D 底行(520 → 548;1920 档换算仍归表现层升级批);③ 关卡画面进度呈现由选路覆盖层节点态直接承载、不另设进度条组件 |
|
||||
+17
-17
@@ -2,7 +2,7 @@
|
||||
|
||||
> **Status**: Complete — /ux-review 修订落稿(2026-09-12,blocking 7 项已修,待复检)
|
||||
> **Author**: user + ux-designer
|
||||
> **Last Updated**: 2026-09-20(敌人卡形态裁决收口:全站桩形态拍板——主角与敌人均无框立绘+底座、状态小图标挂血条下、卡片式退役;B 区行/组件表/线框图/OQ4 同步改写——见文末修订记录)
|
||||
> **Last Updated**: 2026-09-23(停点前移批:A 区关卡进度条退役、布局四区→三区、C/D 底行 548、关卡画面为选路常驻枢纽——见文末修订记录)
|
||||
> **Platform Target**: PC (Steam)——Keyboard/Mouse 主(全部操作纯鼠标可完成)、Gamepad Partial 非 MVP、Touch None(同 technical-preferences)
|
||||
> **上游修订依赖**: 弃图刷新挖掘期受理已随布局决策 4 落稿上游(2026-09-12:行动经济 Active 受理 + 每轮上限 2 次、排雷玩法 Active·仅刷新路径装板、战斗结算 `refresh_board` 编排 + 恒 same_board、registry `rap_rules` 同步——见 OQ11)
|
||||
> **Template**: UX Spec
|
||||
@@ -28,7 +28,7 @@
|
||||
## Player Context on Arrival
|
||||
|
||||
- **首次到达**:从关卡首节点(战×2 的第一战)进入。MVP 无引导流,chord 肌肉记忆提示等非模态提示承担首次教学(见 §States)
|
||||
- **到达前刚在做**:关卡节点图上点击战斗节点(LevelRunner 推进);或上一场战斗胜利后点下一节点
|
||||
- **到达前刚在做**:关卡画面(选路覆盖层常驻形态)上点击战斗节点(LevelRunner 推进);或上一场战斗胜利后返回关卡画面再选下一节点
|
||||
- **情绪状态**:棋手式清明专注(art-bible §2.1,能量 2/10)——挖掘期画面必须无杂音;结算期转为清算爽感(7/10)
|
||||
- **到达方式**:游戏推进送入(非自愿导航),进入即处于挖掘阶段(棋盘已 install、初始 3×3 已展开、小人出生)
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
## Navigation Position
|
||||
|
||||
```
|
||||
存档 → 冒险 → 关卡(节点图,关卡节点地图 lite) → 【战斗屏】
|
||||
├─ 胜利 → 节点奖励/恢复覆盖层 → 下一节点(下一场战斗屏)
|
||||
存档 → 冒险 → 关卡(关卡画面 = 节点图选路常驻枢纽) → 【战斗屏】
|
||||
├─ 胜利 → 节点奖励/恢复覆盖层 → 返回关卡画面选下一节点(→ 下一场战斗屏)
|
||||
├─ 胜利(末节点 Boss)→ 关卡结算(level_clear,清库反馈义务载体 = 魔法道具背包,随魔法道具 P0 落地)→ 下关
|
||||
└─ 失败 → 冒险终结 → 返回存档/营地
|
||||
```
|
||||
|
||||
战斗屏是**上下文相关屏**(仅由战斗节点进入),非顶层常驻。关卡内节点进度常驻屏顶(A 区),玩家始终知道自己身处图中第几环。
|
||||
战斗屏是**上下文相关屏**(仅由战斗节点进入),非顶层常驻。关卡内节点进度常驻关卡画面(选路覆盖层的常驻形态,节点态即进度呈现:已过暗金、当前金、候选通道亮金、Boss 旗朱描边),战斗屏零进度承载——战斗结束返回关卡画面,玩家始终知道自己身处图中第几环。
|
||||
|
||||
- 上游屏:关卡节点图(分支节点图形态,切片第一关为单链特例)
|
||||
- 下游屏:节点奖励/恢复覆盖层(NodeOverlay,已有 demo 组件——建议后续单独出 spec `design/ux/node-reward.md`)
|
||||
@@ -60,7 +60,7 @@
|
||||
| Entry Source | Trigger | Player carries this context |
|
||||
|---|---|---|
|
||||
| 关卡战斗节点 | 点击节点(LevelRunner 推进 encounter) | 携带 HP(跨战斗延续)、RAP=0(战斗域新开) |
|
||||
| 上一场战斗胜利 → 下一节点 | 同上 | 同上 |
|
||||
| 上一场战斗胜利 → 返回关卡画面 → 选下一节点 | 同上 | 同上 |
|
||||
|
||||
**离开**:
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
2. **本轮行动资源**:AP 余量(决定还能挖几格)、停手/弃图刷新按钮——紧贴棋盘上缘(动作发生地)
|
||||
3. **战果兑现面**(结算期为第一注视点):敌人血条变化、逐行结算明细、高光(完美排雷/标中旗)
|
||||
4. **规划面**(边缘注视,常读):HP、攻击、RAP 池、状态效果(己方/敌方)、敌人意图徽标与顺位
|
||||
5. **进度语境**:轮次/阶段指示、关卡节点进度、图例入口
|
||||
5. **进度语境**:轮次/阶段指示、图例入口(关卡节点进度常驻关卡画面,战斗屏不承载——见 Navigation Position)
|
||||
|
||||
依据:挖掘期玩家视线锚定棋盘(art-bible §2.1"视线始终被数字牵引");结算期视线转向战斗画面区(§2.2"兑现光带逐行横扫")。规划信息必须常读但不得抢焦——这正是用户布局图三分下栏的合理性:**动作区居中,规划区两翼**。
|
||||
|
||||
@@ -93,10 +93,11 @@
|
||||
|
||||
| 区 | 位置与尺寸 | 内容 |
|
||||
|---|---|---|
|
||||
| **A 关卡进度条** | 全宽 × 28px 顶栏 | 节点图步进(战 → 战 → 赏 → 战 → 战 → 疗 → 王——文字签槽,对应 battle/reward/rest/boss 四型节点),当前节点奖励金高亮、已过暗金、Boss 旗朱描边 |
|
||||
| **B 战斗画面** | 全宽 × 252px | 主角站桩立绘(左)+ 兑现演出区(中)+ 敌人站桩立绘 ×1–3(右)——**全站桩形态(2026-09-20 用户拍板,敌人卡形态待办裁决收口):主角与敌人均为无框立绘+底座,零卡片**;底部结算明细带(24px 摘要 / 结算期 84px 实时流);顶部中央轮次·阶段指示 |
|
||||
| **C 角色信息** | 左下 240px × 520px | HP 条、攻击值(含修正显示)、RAP 池、状态效果槽(固定 4 槽)、小人立绘占位 |
|
||||
| **D 扫雷图** | 中下 ~1036px × 520px(原右下面板删除后横向加宽,吸收其宽度) | 顶部 AP 条(44px:左——AP 点阵 + 停手按钮;右——图例按钮 + 弃图刷新按钮〔雷图右上角,2026-09-12 拍板〕);棋盘主体(居中,格 36–45px 见方);toast 槽(上缘内侧) |
|
||||
| **C 角色信息** | 左下 240px × 548px | HP 条、攻击值(含修正显示)、RAP 池、状态效果槽(固定 4 槽)、小人立绘占位 |
|
||||
| **D 扫雷图** | 中下 ~1036px × 548px(原右下面板删除后横向加宽,吸收其宽度) | 顶部 AP 条(44px:左——AP 点阵 + 停手按钮;右——图例按钮 + 弃图刷新按钮〔雷图右上角,2026-09-12 拍板〕);棋盘主体(居中,格 36–45px 见方);toast 槽(上缘内侧) |
|
||||
|
||||
> 布局为 B/C/D 三区——关卡进度条不在战斗屏(节点链进度常驻关卡画面,见 Navigation Position;字母不重编沿用 B/C/D)。
|
||||
|
||||
**布局决策 1(本 spec 最大决策,用户拍板)**:**常驻双舞台分屏**——战斗画面与扫雷图同屏常驻,挖掘期敌人待机可见,结算期不切场景。
|
||||
- 备选(已否决):Peglin 式"结算时才切入独立战斗场景"——切换打断推理心流,且资产管线成本翻倍
|
||||
@@ -109,7 +110,6 @@
|
||||
|
||||
| 区 | 组件 | 类型 | 内容 | 交互 | 现有 demo 组件 |
|
||||
|---|---|---|---|---|---|
|
||||
| A | LevelStripView | 步进条 | 节点图 + 当前位置 | 只读(点击节点不可跳) | ✅ level_strip_view.gd 迁移 |
|
||||
| B | 主角站桩立绘 | 站桩(无框立绘+底座) | HP 条悬浮头顶、状态效果小图标一排挂血条正下方(形状+色相双通道、层数角标同 C 区状态槽键);攻击值等规划数据仍归 C 区数据框(2026-09-20 全站桩拍板,英雄卡退役) | 只读 | HUDView 拆分改造 |
|
||||
| B | 敌人站桩立绘 ×1–3 | 站桩(无框立绘+底座) | 血条+顺位徽标悬浮头顶、状态小图标挂血条正下方(敌方 side-wide 增益各立绘同值呈现——蓄力/硬化/削弱/暴走/警觉;伏击层数通道随 2026-09-20 八型批退役——数据源 = 战斗结算流水经增益状态投影,敌人系统×4④;2026-09-16 敌人技能池批改型:行为环点拆除〔proposal §2.4〕,意图占位 = 本拍摇定结果的动画占位——普通攻击零表示 / 特殊技类型级提示,敌方增益〔蓄力/硬化〕入状态图标行);死亡灰化加碎裂退场直接演在立绘上(2026-09-20 全站桩拍板,敌人卡退役) | 只读 | 新建 |
|
||||
| B | 轮次·阶段指示 | 标签 | "第 N 轮 · 挖掘中/结算中"(终局定格「战斗结束」;Boss 变体附 Boss 名) | 只读 | 新建 |
|
||||
@@ -149,13 +149,12 @@
|
||||
|
||||
### ASCII Wireframe
|
||||
|
||||
> **2026-09-23 停点前移批**:A 区关卡进度条退役,下方线框图为 B/C/D 三区(28px 纵向空间划归 C/D 底行 520 → 548;关卡内节点进度常驻关卡画面,战斗屏零进度承载);旧四区线框留档于 git 历史。
|
||||
> **2026-09-20 全站桩形态改版**:敌人卡形态裁决收口(卡片式退役、主角与敌人均站桩——无框立绘+底座、状态小图标挂血条下),下方线框图 B 区已随裁决重绘;旧卡片式线框留档于 git 历史。
|
||||
|
||||
```
|
||||
1280 × 800 ────────────────────────────────────────────────────────────────────
|
||||
┌─[A] 关卡进度条 28px ─────────────────────────────────────────────────────────┐
|
||||
│ 战→战→赏→战→战→疗→王 (当前节点奖励金高亮,已过节点暗金) │
|
||||
├─[B] 战斗画面 252px ──────────────────────────────────────────────────────────┤
|
||||
┌─[B] 战斗画面 252px ──────────────────────────────────────────────────────────┐
|
||||
│ HP▓▓▓▓░ ①HP▓▓▓░ ②HP▓▓░░ │
|
||||
│ ⬆2 🛡1 [⚔特殊技] (普攻·零表示) │
|
||||
│ /小人\ 第 3 轮 · 挖掘中 伏×2 伏×2 │
|
||||
@@ -165,7 +164,7 @@
|
||||
│ │ ▸上轮: 主角攻击3→蛆虫-3 | 攻击+50%(1结算) | 警觉+1×2 … [展开明细▾] │ │ # 2026-09-17 数值压缩批:UI 示意文本同步(atk 7→3〔地精格数÷3 + L1 锚行;UX 示意按当前地精行值读〕、伏击 +3 → +1/层,幅度参考 data/tables/)
|
||||
│ └────────────────────────────────────────────────────────────────────────┘ │
|
||||
├─[C] 角色信息 240px ───┬─[D] 扫雷图 ~1036px ──────────────────────────────────┤
|
||||
│ 520px │ 520px │
|
||||
│ 548px │ 548px │
|
||||
│ ┌──────────────────┐ │ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ HP 42/50 ▓▓▓░ │ │ │ AP ●●●●●○○○ 5/8 │ │
|
||||
│ │ 攻击 6 (+50%) │ │ │ [⏹停手] [?图例] [↻刷新 8|剩2] │ │
|
||||
@@ -281,7 +280,7 @@
|
||||
| 敌单位 hp/顺位/摇定动作(pending_skill/type/name)/敌方增益/enemy_id/存活 | 敌人系统 只读面(经战斗结算呈现快照) | Read | 意图线索映射全局恒定(敌人系统×4②,技能池批三档口径);**despawn 前捕获**(旧版台账 entry 17③——缺陷②教训) |
|
||||
| 状态效果投影(含空态/极性/溢出) | 增益状态 投影口径 | Read | 极性映射数据源 = 战斗结算 SettlementTable 效果语义,非 magnitude 符号(增益状态×③) |
|
||||
| 已开格奖励身份(奖励徽章) | 地图战斗资源 `query_identity`(经 board_view 身份解析只读回调,组合根注入) | Read | 已开格身份常读——挖掘期 Active 相位内有效;reward_id 全局恒定、禁止重掷;徽章绘制优先级见 §Component Inventory BoardView 行 |
|
||||
| 节点图/当前节点/HP 携带 | 关卡节点地图 lite · LevelRunner | Read | A 区进度条 |
|
||||
| 节点图/当前节点/HP 携带 | 关卡节点地图 lite · LevelRunner | Read | 关卡画面选路覆盖层节点态呈现(战斗屏零进度承载) |
|
||||
| 意图提交 | 排雷玩法 | **Write** | `settle_batch`(stop 亦经此——不直调行动经济) |
|
||||
| 弃图刷新 | 行动经济 | **Write** | `request_refresh`(挖掘期 Active 当场受理——布局决策 4 2026-09-12 上游已落稿;战斗结算 `refresh_board` 编排承载) |
|
||||
| 节点推进 | LevelRunner | **Write** | 胜利 overlay「下一节点」 |
|
||||
@@ -321,7 +320,7 @@
|
||||
|
||||
**布局与可读**
|
||||
|
||||
- [ ] 1280×800 与 16:9 全屏(canvas_items/expand)下四区无遮挡、无重叠、无内容裁切(棋盘 12×12 全部格子 + 数字完整可见)
|
||||
- [ ] 1280×800 与 16:9 全屏(canvas_items/expand)下三区(B/C/D)无遮挡、无重叠、无内容裁切(棋盘 12×12 全部格子 + 数字完整可见)
|
||||
- [ ] 进入战斗屏 ≤500ms 内可交互(棋盘 install 淡入完成后首格可点);同屏 draw calls < 200(technical-preferences 预算)
|
||||
- [ ] 两种格态(已开格 / 未开格)灰度截图下一眼可辨(排雷玩法×6②)
|
||||
- [ ] 悬停光标区分移动/挖/旗三语义;可挖域(8 向相邻)常驻指示;非相邻格悬停显禁止反馈(排雷玩法×6③)
|
||||
@@ -404,3 +403,4 @@
|
||||
| 2026-09-15 | 雾格残留清理:格态收窄为已开 / 未开两态(删除雾图变体状态行、四格态 AC 与已开雾格 tint / 雾区全开信号两条 AC);图例面板与 toast 槽去掉雾条目与雾首遇提示;BoardView 纹带、绘制优先级与色弱冗余改按通用变异纹带表述;`ux_hint_shown` 的 hint_id 枚举去掉 fog_first;输入义务与 §13 义务对照表去掉 地形变异×3 一项;目标感知示例与提示文案 OQ 措辞同步。本 spec 不装载被移除机制的呈现义务 |
|
||||
| 2026-09-16 | 格面资源批 UI 欠账收口(随 2026-09-15 可选类道具删除的代码收口同步文档):① 布局四区化——删 E 区道具面板行、布局决策 2(道具窗口形态=右栏原位激活)整段删除(编号留空防交叉引用失锚)、ASCII 线框图重绘为 A/B/C/D 四区(D 区横向加宽 ~1036px)、A 区节点链示例改文字签槽实际渲染(战/赏/疗/王);② States 删道具窗口态与零库存空态(「道包空空」);③ 结算口径五段化(授予→增益/减益→战斗→衰减→判定)与明细行 10 类封闭协议(删 15 类行、四类行旧口径;「奖励未生效」行保留);④ 交互/动效/事件表删道具窗口行、跳过按钮、`ux_window_choice`、`submit_window_selection`;⑤ 数据源登记删 `query_inventory` 与窗口载荷,奖励身份按现行 `query_identity` 只读回调口径校正;⑥ 验收清单删窗口断言、五区改四区、未生效类行改现行两型(溢出未生效/奖励未生效);⑦ 关卡末清库反馈义务改载魔法道具背包(随魔法道具 P0 落地,本批不设计具体呈现);⑧ OQ7(道具窗口原位激活)删除、OQ 重编号,「囤刀待机」等旧可选类措辞清理。本 spec 不装载被删除机制的呈现义务 |
|
||||
| 2026-09-20 | **敌人卡形态裁决收口(2026-09-20 用户看对照样张拍板,06 待办「敌人卡形态」解决移除——台账 99)**:全站桩形态定稿——① B 区主角与敌人均为无框立绘+底座(站桩式),**英雄卡/敌人卡组件整体退役,卡片式不再作为候选**;主角血条悬浮头顶、状态效果小图标一排挂血条正下方,敌人血条+顺位徽标悬浮头顶、状态小图标同款挂血条下;攻击值等规划数据仍归 C 区数据框(C 区不动);② 布局表 B 区行、Component Inventory 英雄卡/敌人卡两行随裁决改写(敌方 side 池共享层数各立绘同值、意图动画占位等既有语义平移到站桩载体,不随形态改变);③ ASCII 线框图 B 区重绘(旧"意图:爪击/环点"示意早已随行为环退役,本次一并清掉);④ OQ4 改写为裁决已收口注记,对照样张存档 `production/mockups/`;呈现义务细节重述(受击/退场演出挂点等)随表现层升级批执行 |
|
||||
| 2026-09-23 | **停点前移批(冒险入口流程倒置修复,用户 2026-09-23 拍板;上位裁决 `docs/architecture/adr-0006-board-node2d-rendering.md` 与 `docs/architecture/board-node2d-migration-plan.md` §1,代码实装另批并行)**:① 布局四区 → 三区——删布局表 A 区关卡进度条行与 Component Inventory LevelStripView 行(LevelStripView 退役删除,节点链进度只留关卡画面,战斗屏零进度承载);C/D 底行 520 → 548;ASCII 线框图重绘为 B/C/D 三区;② 新流程口径落文——关卡画面(选路覆盖层常驻形态)为关卡内常驻枢纽:Navigation Position 图、到达语境、Entry 表、信息层级第 5 层、Data Requirements 节点图行改「关卡开始即出图选路、战后返回关卡画面再选路」;③ AC 四区措辞改三区。**批内代拍板三项待追认**:① B/C/D 字母保持不重编;② 28px 纵向空间划归 C/D 底行(520 → 548);③ 关卡画面进度呈现由选路覆盖层节点态承载(暗金已过 / 金当前 / 亮金候选通道 / 旗朱 Boss)、不另设进度条组件 |
|
||||
@@ -24,6 +24,12 @@
|
||||
# continue_to_next_level 开始下一关,两步间为呈现层大奖励屏(冒烟/自动路径立即确认)。
|
||||
# 结算受理只算一次(契约):state != "running" 的关卡结束宣布与放弃请求一律拒绝并留诊断,
|
||||
# 账本与摘要零变化。
|
||||
# 停点前移批(2026-09-23,用户拍板「关卡开始即出节点图选路、选节点才进战斗」):每关开始 =
|
||||
# 入口选路停点——_start_current_level 以 defer_entry 起关,level_started 之后才 present_entry_choice
|
||||
# (信号顺序契约:呈现层先重取 runner 实例,选路口才不会被空防御丢弃);pick 入口候选走同一
|
||||
# _enter_node(entry)、呈现零 RNG 消耗——与旧「start 直进首战」逐位等价,测量面零漂移。
|
||||
# 关卡切换(continue_to_next_level)后新 LevelRunner 实例重新走 defer 流程;abandon 在入口停点
|
||||
# 天然非战斗期(current_battle 为空)——受理语义与选路停点一致。
|
||||
# 纪律:ADR-0001 S6——连 runner 信号一律 _forward_* 方法 Callable(禁 lambda 捕获 self 成环);
|
||||
# Core 层禁 UI 引用;数值零字面量——level_clear_hp_bonus / keystone_per_level 只读 db.adventure,
|
||||
# 基础上限只读 db.hero。
|
||||
@@ -153,11 +159,15 @@ func _start_current_level() -> bool:
|
||||
_runner.level_finished.connect(_on_level_finished)
|
||||
_runner.set_hero_override(int(_override[0]), int(_override[1]))
|
||||
# 接口①开始关卡:生命经共享账本交接(账本当前值即开局生命——冒险开始置满 / 大奖励回满已写好);
|
||||
# _base_override 共享引用随载荷传入(永久强化 flat——LevelRunner.effective_* 叠加序第二项)
|
||||
# _base_override 共享引用随载荷传入(永久强化 flat——LevelRunner.effective_* 叠加序第二项)。
|
||||
# 停点前移批 2026-09-23:defer_entry=true 起每关(含首关)——先 emit level_started(呈现层在
|
||||
# 该回调重取 runner 实例),后 present_entry_choice()(入口候选呈现;顺序反了选路口会被呈现层
|
||||
# 的 runner 空防御静默丢弃)。呈现零 RNG 消耗、pick 走同一 _enter_node——测量面逐位零漂移。
|
||||
var ok: bool = _runner.start_level_external(level_index, ledger, bonus, purchased,
|
||||
Callable(self, "apply_rest"), _base_override)
|
||||
Callable(self, "apply_rest"), _base_override, true)
|
||||
if ok:
|
||||
level_started.emit(level_index, String(_runner.level_row.get("display_name", "")))
|
||||
_runner.present_entry_choice()
|
||||
return ok
|
||||
|
||||
|
||||
|
||||
@@ -158,8 +158,15 @@ func start_level(level_index: int, seed_val: int, base_override_in: Dictionary =
|
||||
# base_override = 永久强化 flat 共享引用(元进度实现批——缺省 {} 全零白板,与 B1 空参数路径逐位一致)。
|
||||
# 流程与 start_level 同款(_find_level_row → 状态初始化 → _graph_mode 探测 → _enter_node(entry)),
|
||||
# 差异仅在账本/加算区/已购档/恢复执行体的注入与零重置。
|
||||
# 停点前移批 2026-09-23:defer_entry 尾参(缺省 false = 既有调用方零变更)——true 时不自动
|
||||
# _enter_node(entry),改置选路态(awaiting_choice + 单候选 = 入口节点),由 AdventureRunner 在
|
||||
# level_started 之后调 present_entry_choice() 呈现、玩家 pick_next_node 显式进首战。拆两步的
|
||||
# 信号顺序契约:呈现层须先经 level_started 重取 runner 实例,choices_presented 才不会被
|
||||
# _on_choices_presented 的 runner 空防御静默丢弃。入口呈现零 RNG 消耗、pick 走同一个
|
||||
# _enter_node(entry)——与旧自动进入逐位等价(测量面零漂移红线)。
|
||||
func start_level_external(level_index: int, ledger: Dictionary, bonus_ref: Dictionary,
|
||||
purchased_ref: Dictionary, rest_handler: Callable, base_override_ref: Dictionary = {}) -> bool:
|
||||
purchased_ref: Dictionary, rest_handler: Callable, base_override_ref: Dictionary = {},
|
||||
defer_entry: bool = false) -> bool:
|
||||
var row := _find_level_row(level_index)
|
||||
if row.is_empty():
|
||||
push_error("[关卡节点地图] level_index %d 在 LevelTable 无行" % level_index)
|
||||
@@ -187,9 +194,23 @@ func start_level_external(level_index: int, ledger: Dictionary, bonus_ref: Dicti
|
||||
push_error("[关卡节点地图] 入口节点缺失(无入边唯一节点——图合法性校验应已拦截)")
|
||||
_running = false
|
||||
return false
|
||||
if defer_entry:
|
||||
_awaiting_choice = true # 入口停点(node_index 保持 -1——进节点前无 current_node)
|
||||
_candidates = [entry]
|
||||
return true
|
||||
return _enter_node(entry)
|
||||
|
||||
|
||||
# 入口停点呈现(停点前移批 2026-09-23——defer_entry=true 的第二步):发出入口候选供呈现层弹
|
||||
# 选路层;非停点态(缺省自动进入路径)拒绝。零 RNG 消耗——呈现与行进取号解耦。
|
||||
func present_entry_choice() -> bool:
|
||||
if not _running or not _awaiting_choice or _candidates.is_empty() or node_index != -1:
|
||||
push_error("[关卡节点地图] present_entry_choice 拒绝——非入口停点态(defer_entry 未开或已 pick)")
|
||||
return false
|
||||
choices_presented.emit(_candidates)
|
||||
return true
|
||||
|
||||
|
||||
func _find_level_row(level_index: int) -> Dictionary:
|
||||
for row in db.level.rows:
|
||||
if int(row.level_index) == level_index:
|
||||
|
||||
@@ -48,17 +48,17 @@ var route_overlay: RouteOverlay # 节点图选路覆盖层(分支节点图
|
||||
# 调试模式编排(单场/连续两层——状态机与战斗生命周期归 debug_session.gd,本类只接线与出 UI)
|
||||
var _debug = null
|
||||
|
||||
# 视图(views/)——battle.md 四区(E 区道具面板随可选类删除下线)
|
||||
var strip_view: LevelStripView # A 区
|
||||
# 视图(views/)——battle.md 三区(A 区关卡进度条顶栏随 停点前移批 2026-09-23 退役——节点链进度
|
||||
# 由关卡画面本体选路覆盖层承载;E 区道具面板随可选类删除下线)
|
||||
var stage: BattleStageView # B 区(含 log_view 明细带)
|
||||
var log_view: BattleLogView
|
||||
var info_panel: HeroInfoPanelView # C 区
|
||||
var info_panel: HeroInfoPanelView # C 区(含钱包行——原 A 区顶栏 GP/钥石余额常驻位)
|
||||
var board_zone: BoardZoneView # D 区(含 ap_bar/board_view/toast/fx)
|
||||
var board_view: BoardView # 探针兼容别名(= board_zone.board_view)
|
||||
var ap_bar: ApBarView # 探针兼容别名(= board_zone.ap_bar)
|
||||
var settlement_fx: SettlementFxView # 结算演出覆盖层(跨区弹道/光带——A–D 之上、模态之下)
|
||||
var gp_label: Label # A 区顶栏 GP 余额常驻位(GP+商店房实施批——文案装配归 HudPresenter)
|
||||
var keystone_label: Label # A 区顶栏钥石余额常驻位(元进度实现批——文案装配归 HudPresenter)
|
||||
var gp_label: Label # GP 余额常驻位(C 区钱包行——文案装配归 HudPresenter)
|
||||
var keystone_label: Label # 钥石余额常驻位(C 区钱包行——文案装配归 HudPresenter)
|
||||
# 模态 overlay(z 序 = 登记序;pattern 6 层级纪律)
|
||||
var legend_overlay: LegendOverlay
|
||||
var review_overlay: SettlementReviewOverlay
|
||||
@@ -102,7 +102,6 @@ func _build_ui() -> void:
|
||||
var root := VBoxContainer.new()
|
||||
add_child(root)
|
||||
var battle_ui: Dictionary = UiAssembler.build_battle_ui(root, db)
|
||||
strip_view = battle_ui.strip_view
|
||||
gp_label = battle_ui.gp_label
|
||||
keystone_label = battle_ui.keystone_label
|
||||
stage = battle_ui.stage
|
||||
@@ -248,10 +247,10 @@ func _start_adventure() -> void:
|
||||
return
|
||||
|
||||
|
||||
# 每关开始(冒险模式):重取 runner 实例 + 图条刷新 + 层名行(L1 与单关模式同序——层名行随首战横幅后到达)
|
||||
# 每关开始(冒险模式):重取 runner 实例 + 层名行(L1 与单关模式同序——层名行随首战横幅后到达;
|
||||
# 停点前移批 2026-09-23:本回调返回后才有 choices_presented 到达——入口选路层随即弹出)
|
||||
func _on_adventure_level_started(level_index: int, display_name: String) -> void:
|
||||
runner = adventure.runner()
|
||||
strip_view.refresh(runner)
|
||||
log_view.append_bb(Narrator.level_open_line(display_name, int(adventure.master_seed),
|
||||
int(db.hero.atk), int(db.hero.max_hp),
|
||||
tune_panel.atk_pct() > 0 or tune_panel.hp_pct() > 0))
|
||||
@@ -291,7 +290,6 @@ func _on_runner_node(node: Dictionary, info: Dictionary) -> void:
|
||||
shop_overlay.open_shop(runner.shop_products(), int(runner.gp))
|
||||
log_view.append_bb(Narrator.shop_line(int(runner.gp)))
|
||||
logger.log_node(node, info, runner.node_index)
|
||||
strip_view.refresh(runner)
|
||||
_refresh_presentations()
|
||||
|
||||
|
||||
@@ -329,7 +327,6 @@ func _on_adventure_finished(summary: Dictionary) -> void:
|
||||
logger.log_level_end(summary) # 试玩时间线:冒险终局(摘要随载荷)
|
||||
if runner != null:
|
||||
runner.restore_hero_base()
|
||||
strip_view.refresh(runner)
|
||||
_open_modal(_end_overlay)
|
||||
_refresh_presentations()
|
||||
|
||||
@@ -355,7 +352,6 @@ func _on_battle_end_continue() -> void:
|
||||
adventure = null
|
||||
_adventure_mode = false
|
||||
tune_panel.reset_sliders()
|
||||
strip_view.refresh(null)
|
||||
_start_overlay.visible = true
|
||||
_refresh_presentations()
|
||||
|
||||
|
||||
@@ -7,39 +7,22 @@
|
||||
extends RefCounted
|
||||
|
||||
|
||||
# 战斗屏四区(A 进度条 / B 战斗画面 / C·D 两列——E 区道具面板已随可选类删除下线,2026-09-15 格面资源批)
|
||||
# 战斗屏三区(B 战斗画面 / C·D 两列——A 区关卡进度条顶栏随 停点前移批 2026-09-23 退役:节点链
|
||||
# 进度由关卡画面本体(选路覆盖层整图)承载,28px 纵向空间拨给 C/D 底行 520→548;E 区道具面板
|
||||
# 已随可选类删除下线,2026-09-15 格面资源批)。
|
||||
# + 结算演出覆盖层(A–D 之上、模态之下——跨区弹道/光带载体,结算演出链批 2026-09-20)。
|
||||
# 返回句柄字典:{strip_view, gp_label, stage, log_view, info_panel, board_zone, board_view, ap_bar, settlement_fx}
|
||||
# 返回句柄字典:{gp_label, keystone_label, stage, log_view, info_panel, board_zone, board_view, ap_bar, settlement_fx}
|
||||
static func build_battle_ui(root: Control, db) -> Dictionary:
|
||||
# set_anchors_and_offsets_preset(非 set_anchors_preset):后者会把控件重置回最小内容尺寸
|
||||
# (实测 927×613——缩顶、棋盘 45px 格 ×10 行超出 D 区 333px 高被裁,2026-09-13 用户报告回归)
|
||||
root.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
root.add_theme_constant_override("separation", 0)
|
||||
|
||||
# A 区:关卡进度条(全宽 × 28px 顶栏)+ GP 余额常驻位(GP+商店房实施批 2026-09-21——
|
||||
# 顶栏邻接位,显示名「金币」;文案装配归 HudPresenter,此处只建节点)
|
||||
var strip_panel := PanelContainer.new()
|
||||
strip_panel.custom_minimum_size = Vector2(0, 28)
|
||||
var sb := UiKit.panel_flat(UiKit.BG_ROOT, UiKit.BG_ROOT, 0, 0)
|
||||
strip_panel.add_theme_stylebox_override("panel", sb)
|
||||
root.add_child(strip_panel)
|
||||
var strip_row := HBoxContainer.new()
|
||||
strip_panel.add_child(strip_row)
|
||||
var strip_view := LevelStripView.new()
|
||||
strip_view.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
strip_row.add_child(strip_view)
|
||||
var gp_label := UiKit.label("金币 0", 15, true)
|
||||
gp_label.add_theme_color_override("font_color", UiKit.GOLD_DEEP)
|
||||
strip_row.add_child(gp_label)
|
||||
var keystone_label := UiKit.label("钥石 0", 15, true) # 元进度实现批——A 区顶栏钥石余额常驻(文案装配归 HudPresenter,此处只建节点)
|
||||
keystone_label.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
strip_row.add_child(keystone_label)
|
||||
|
||||
# B 区:战斗画面(全宽 × 252px——常驻双舞台,布局决策 D1)
|
||||
var stage := BattleStageView.new(db)
|
||||
root.add_child(stage)
|
||||
|
||||
# C/D 两列(520px)——E 区库存面板删除后 D 区横向加宽
|
||||
# C/D 两列(548px——停点前移批 2026-09-23:原 A 区 28px 顶栏纵向空间并入)
|
||||
var bottom := HBoxContainer.new()
|
||||
bottom.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
bottom.add_theme_constant_override("separation", 4)
|
||||
@@ -56,10 +39,11 @@ static func build_battle_ui(root: Control, db) -> Dictionary:
|
||||
var settlement_fx := SettlementFxView.new()
|
||||
root.add_child(settlement_fx)
|
||||
|
||||
# GP/钥石余额常驻位(GP+商店房实施批 2026-09-21 原居 A 区顶栏——顶栏退役后迁 C 区底行,
|
||||
# 句柄经 info_panel 视图成员透出;文案装配归 HudPresenter,此处只透传引用)
|
||||
return {
|
||||
"strip_view": strip_view,
|
||||
"gp_label": gp_label,
|
||||
"keystone_label": keystone_label,
|
||||
"gp_label": info_panel.gp_label,
|
||||
"keystone_label": info_panel.keystone_label,
|
||||
"stage": stage,
|
||||
"log_view": stage.log_view,
|
||||
"info_panel": info_panel,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# 实现 GDD:design/ux/battle.md(D 区扫雷图 ~760×520 容器——顶部 AP 条 44px〔左:点阵+停手;
|
||||
# 实现 GDD:design/ux/battle.md(D 区扫雷图 ~760×548 容器〔底行 520→548——停点前移批 2026-09-23,
|
||||
# 原 A 区顶栏空间并入〕——顶部 AP 条 44px〔左:点阵+停手;
|
||||
# 右:图例+弃图刷新〕、棋盘主体居中、toast 槽上缘内侧、演出层)。
|
||||
# Date: 2026-09-12
|
||||
# 高内聚边界:容器组合 + 信号转发——动作意图全部信号外发到组合根,零核心写调用。
|
||||
|
||||
+18
-1
@@ -1,5 +1,6 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# 实现 GDD:design/ux/battle.md(C 区角色信息 240×520——HP/攻击(+修正)/RAP 直角细线数据框
|
||||
# 实现 GDD:design/ux/battle.md(C 区角色信息 240×548〔底行 520→548——停点前移批 2026-09-23,
|
||||
# 原 A 区顶栏空间并入〕——HP/攻击(+修正)/RAP 直角细线数据框
|
||||
# 〔修正来源角标〕、状态效果槽 ×4、小人立绘占位;RAP 清零可见反馈〔行动经济 义务〕;
|
||||
# 状态槽空态 = 槽隐藏上移补位〔EC12〕)。
|
||||
# Date: 2026-09-12
|
||||
@@ -20,6 +21,8 @@ var _rap_label: Label
|
||||
var _rap_feedback: Label
|
||||
var _status_feedback: Label
|
||||
var slot_row: StatusSlotRow
|
||||
var gp_label: Label # 冒险钱包余额常驻位(停点前移批 2026-09-23——原 A 区顶栏迁入 C 区底行)
|
||||
var keystone_label: Label # 钥石余额常驻位(同上——文案装配归 HudPresenter)
|
||||
var _last_rap := 0 # 上次投影值(清零反馈判据——禁解析自身 label 文本当状态)
|
||||
|
||||
|
||||
@@ -76,6 +79,20 @@ func _init() -> void:
|
||||
portrait_glyph.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
portrait.add_child(portrait_glyph)
|
||||
|
||||
# 钱包行(停点前移批 2026-09-23:A 区 28px 顶栏退役——GP/钥石余额常驻位迁本面板底行,
|
||||
# 建节点归视图、文案装配归 HudPresenter,句柄经 ui_assembler 透传组合根)
|
||||
var wallet_row := HBoxContainer.new()
|
||||
wallet_row.add_theme_constant_override("separation", 10)
|
||||
col.add_child(wallet_row)
|
||||
gp_label = UiKit.label("金币 0", 15, true)
|
||||
gp_label.add_theme_color_override("font_color", UiKit.GOLD_DEEP)
|
||||
wallet_row.add_child(gp_label)
|
||||
keystone_label = UiKit.label("钥石 0", 15, true)
|
||||
keystone_label.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
keystone_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
keystone_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||
wallet_row.add_child(keystone_label)
|
||||
|
||||
|
||||
func set_hero(hp: int, max_hp: int) -> void:
|
||||
_hp_bar.max_value = maxi(1, max_hp)
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
# 实现 GDD:design/ux/battle.md(A 区关卡进度条——全宽 × 28px 顶栏,当前节点高亮、已过节点暗金)。
|
||||
# Date: 2026-09-12(battle.md 战斗屏改造批——对齐 28px 顶栏与高亮样式;基础 = 2026-09-11 关卡节点地图-lite 呈现)
|
||||
# 2026-09-17 分支节点图批:图形态行集渲染 = 行进序列(已到暗金 → 当前金 → 可选下一跳亮边候选);
|
||||
# 单链形态(第一关零迁移)保持全链横条渲染。
|
||||
# 高内聚边界:只读 runner 的节点链/进度/候选做渲染,无任何写面。
|
||||
class_name LevelStripView
|
||||
extends HBoxContainer
|
||||
|
||||
const COL_DONE := UiKit.GOLD_DIM # 已过——暗金
|
||||
const COL_CURRENT := UiKit.GOLD # 当前——奖励金高亮
|
||||
const COL_UPCOMING := UiKit.DARK_UPCOMING
|
||||
const COL_CANDIDATE := UiKit.GOLD_LIT # 候选下一跳——亮金边框
|
||||
const COL_BOSS_BORDER := UiKit.FLAG_RED # Boss 边框——旗朱
|
||||
const NODE_LABELS := {"battle": "战", "reward": "赏", "rest": "疗", "boss": "王", "shop": "商"} # 商 = GP+商店房实施批 2026-09-21
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
add_theme_constant_override("separation", 6)
|
||||
custom_minimum_size = Vector2(0, 28) # A 区 28px 顶栏(battle.md §Layout)
|
||||
|
||||
|
||||
func refresh(runner) -> void:
|
||||
for child in get_children():
|
||||
child.queue_free()
|
||||
if runner == null:
|
||||
return
|
||||
var nodes: Array = runner.nodes()
|
||||
for node in nodes:
|
||||
if node.has("next"):
|
||||
refresh_graph(runner)
|
||||
return
|
||||
_refresh_chain(runner, nodes)
|
||||
|
||||
|
||||
# 单链形态(退化观感 = 全链横条——第一关现状渲染)
|
||||
func _refresh_chain(runner, nodes: Array) -> void:
|
||||
for i in nodes.size():
|
||||
var node: Dictionary = nodes[i]
|
||||
var type := String(node.get("type", ""))
|
||||
add_child(_node_chip(type, _node_color(i, runner), false))
|
||||
if i < nodes.size() - 1:
|
||||
add_child(_arrow())
|
||||
|
||||
|
||||
# 图形态:行进序列 → 当前 → 可选下一跳(编号显示经 runner 编号空间读面)
|
||||
func refresh_graph(runner) -> void:
|
||||
var visited: Array = runner.visited
|
||||
var cands: Array = runner.next_candidates()
|
||||
for i in visited.size():
|
||||
var node: Dictionary = visited[i]
|
||||
var is_current: bool = i == visited.size() - 1 and String(runner.level_result) == ""
|
||||
add_child(_node_chip(String(node.get("type", "")), COL_CURRENT if is_current else COL_DONE, false,
|
||||
runner.node_id_of(node)))
|
||||
add_child(_arrow())
|
||||
for j in cands.size():
|
||||
var cand: Dictionary = cands[j]
|
||||
add_child(_node_chip(String(cand.get("type", "")), COL_UPCOMING, true, runner.node_id_of(cand)))
|
||||
if j < cands.size() - 1:
|
||||
add_child(_arrow())
|
||||
|
||||
|
||||
func _arrow() -> Label:
|
||||
var arrow := UiKit.label("→", 13, false)
|
||||
arrow.add_theme_color_override("font_color", UiKit.STONE)
|
||||
return arrow
|
||||
|
||||
|
||||
func _node_color(i: int, runner) -> Color:
|
||||
var finished: bool = i < int(runner.node_index) or String(runner.level_result) != ""
|
||||
var is_current: bool = i == int(runner.node_index) and String(runner.level_result) == ""
|
||||
if is_current:
|
||||
return COL_CURRENT
|
||||
if finished:
|
||||
return COL_DONE
|
||||
return COL_UPCOMING
|
||||
|
||||
|
||||
func _node_chip(type: String, col: Color, candidate_border: bool, node_id: int = -1) -> PanelContainer:
|
||||
var p := PanelContainer.new()
|
||||
var border := col
|
||||
var border_w := 0
|
||||
if type == "boss":
|
||||
border = COL_BOSS_BORDER
|
||||
border_w = 2
|
||||
elif candidate_border:
|
||||
border = COL_CANDIDATE
|
||||
border_w = 2
|
||||
var sb := UiKit.panel_flat(col, border, 4, border_w, Vector4(9, 2, 9, 2))
|
||||
p.add_theme_stylebox_override("panel", sb)
|
||||
var text := String(NODE_LABELS.get(type, "?"))
|
||||
if node_id >= 0:
|
||||
text += str(node_id)
|
||||
var l := UiKit.label(text, 15, true)
|
||||
l.add_theme_color_override("font_color", UiKit.INK_TITLE if col != COL_UPCOMING else UiKit.DARK_TEXT_FAINT)
|
||||
p.add_child(l)
|
||||
return p
|
||||
@@ -1 +0,0 @@
|
||||
uid://mv5cxybk4mf0
|
||||
@@ -67,6 +67,9 @@ static func run_level(db, seed_val: int, level_index: int, atk_pct: int, hp_pct:
|
||||
|
||||
|
||||
# 单关驱动段(run_level 抽取——零自动推进停点 + 战斗自动玩家;policy 经 st 入 _autoplay_battle)
|
||||
# 停点前移批 2026-09-23:入口停点(node_index 尚 -1 = 进节点前无 current_node)也经本分支驱动——
|
||||
# 读 next_candidate_ids 候选(入口单候选)→ pick_next_node,同一 _enter_node 与旧自动进入逐位
|
||||
# 等价(零 RNG 漂移);入口 pick 不计 st.choices(单候选强制选路,计数口径与旧测量面逐位同构)。
|
||||
static func _drive_level(runner, st: Dictionary, logger, policy: String, route: String) -> void:
|
||||
st["policy"] = policy
|
||||
var guard_battles := 20
|
||||
@@ -74,8 +77,9 @@ static func _drive_level(runner, st: Dictionary, logger, policy: String, route:
|
||||
while st.result == "" and guard_battles > 0 and guard_actions > 0:
|
||||
guard_actions -= 1
|
||||
if runner.awaiting_choice():
|
||||
# 选路态(兑付确认/战斗胜利后的零自动推进停点)——route 策略显式选下一跳
|
||||
st.choices = int(st.choices) + 1
|
||||
# 选路态(入口停点 / 兑付确认 / 战斗胜利后的零自动推进停点)——route 策略显式选下一跳
|
||||
if runner.node_index >= 0:
|
||||
st.choices = int(st.choices) + 1
|
||||
runner.pick_next_node(_route_pick(runner, route))
|
||||
continue
|
||||
guard_battles -= 1
|
||||
|
||||
@@ -120,14 +120,28 @@ func _smoke_adventure_table() -> void:
|
||||
check(ks >= 0 and ks <= 999, "keystone_per_level ∈ [0,999](%d)" % ks)
|
||||
|
||||
|
||||
# ② 冒险结构 API 闸(状态机受理面——重复开始拒绝 / 放弃两态)
|
||||
# ② 冒险结构 API 闸(状态机受理面——重复开始拒绝 / 入口停点 / 放弃两态)
|
||||
func _smoke_adventure_api() -> void:
|
||||
print("--- 冒险结构 API 闸(重复开始拒绝 · 放弃两态受理)---")
|
||||
print("--- 冒险结构 API 闸(重复开始拒绝 · 入口停点 · 放弃两态受理)---")
|
||||
var adr = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(42))
|
||||
adr.set_hero_override(900, 400) # 首战速胜档(放弃的非战斗受理要走到选路态)
|
||||
# 停点前移批 2026-09-23:入口停点观测(信号序 + 入口候选快照——容器写回规避 lambda 按值捕获)
|
||||
var sig_seq: Array = []
|
||||
var obs := {"entry_cands": []}
|
||||
adr.level_started.connect(_api_mark_started.bind(sig_seq))
|
||||
adr.choices_presented.connect(_api_mark_choices.bind(sig_seq, obs))
|
||||
adr.node_entered.connect(_api_mark_node.bind(sig_seq))
|
||||
check(adr.start_adventure(42), "冒险启动受理(主种子注入恰一次——state=running)")
|
||||
check(not adr.start_adventure(43), "进行中重复 start_adventure 拒绝(重开须待结算完毕)")
|
||||
check(adr.runner().current_battle() != null, "首战在飞(接口①开始关卡直达战斗节点)")
|
||||
check(sig_seq.size() == 2 and String(sig_seq[0]) == "level_started" and String(sig_seq[1]) == "choices_presented",
|
||||
"停点前移次序契约:level_started 先于入口候选呈现(反序选路口会被呈现层 runner 空防御丢弃)")
|
||||
check(adr.runner().awaiting_choice() and (obs["entry_cands"] as Array).size() == 1 \
|
||||
and adr.runner().current_battle() == null,
|
||||
"入口停点:选路态 + 入口单候选 + 首战未开(呈现零 RNG 消耗——pick 前零战斗域)")
|
||||
check(adr.runner().pick_next_node(int(adr.runner().next_candidate_ids()[0])),
|
||||
"pick 入口候选受理(同一 _enter_node——与旧自动进入逐位等价)")
|
||||
check(sig_seq.size() == 3 and String(sig_seq[2]) == "node_entered" and adr.runner().current_battle() != null,
|
||||
"pick 后 node_entered 到达 + 首战在飞(接口①开始关卡——停点闭合直达战斗节点)")
|
||||
check(not adr.abandon(), "战斗中 abandon 拒绝(战斗域单事务在飞)")
|
||||
# 驱动首战到胜利 → 选路态(非战斗期)→ abandon 受理
|
||||
var autoplay = load("res://smoke/level_autoplay.gd")
|
||||
@@ -146,6 +160,20 @@ func _smoke_adventure_api() -> void:
|
||||
check(not adr.abandon(), "结算后重复 abandon 拒绝(结算受理只算一次——state=idle)")
|
||||
|
||||
|
||||
# 停点前移批 2026-09-23 观测桩(信号序采集——bind 容器写回,签名按各信号实参定制)
|
||||
func _api_mark_started(_li: int, _dn: String, seq: Array) -> void:
|
||||
seq.append("level_started")
|
||||
|
||||
|
||||
func _api_mark_choices(cands: Array, seq: Array, obs: Dictionary) -> void:
|
||||
seq.append("choices_presented")
|
||||
obs["entry_cands"] = cands.duplicate()
|
||||
|
||||
|
||||
func _api_mark_node(_node: Dictionary, _info: Dictionary, seq: Array) -> void:
|
||||
seq.append("node_entered")
|
||||
|
||||
|
||||
# ③ 冒险验收断言(映射 冒险结构.md 验收标准——表覆盖/满配通关/种子复现/大奖励/败北线/
|
||||
# 重复拒绝/GP 跨关延续/加算区同账/恢复数学/放弃)
|
||||
func _smoke_adventure() -> void:
|
||||
@@ -244,6 +272,7 @@ func _smoke_adventure() -> void:
|
||||
var adr6 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(7))
|
||||
adr6.set_hero_override(900, 400)
|
||||
check(adr6.start_adventure(7), "重复拒绝场景:冒险启动(seed 7)")
|
||||
adr6.runner().pick_next_node(int(adr6.runner().next_candidate_ids()[0])) # 停点前移批 2026-09-23:入口停点 pick 进首战
|
||||
var b6 = adr6.runner().current_battle()
|
||||
var st6 := _adv_st()
|
||||
var g6 := 30
|
||||
@@ -314,7 +343,9 @@ func _smoke_adventure() -> void:
|
||||
# ⑩ 放弃(战斗中拒绝 · 非战斗期受理同失败型结算)
|
||||
var a10 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(15))
|
||||
a10.set_hero_override(900, 400)
|
||||
check(a10.start_adventure(15), "放弃场景:冒险启动(seed 15——首战在飞)")
|
||||
check(a10.start_adventure(15), "放弃场景:冒险启动(seed 15)")
|
||||
check(a10.runner().pick_next_node(int(a10.runner().next_candidate_ids()[0])),
|
||||
"放弃场景:入口停点 pick 进首战(停点前移批 2026-09-23 驱动口径)")
|
||||
check(not a10.abandon(), "战斗中 abandon 拒绝(战斗域单事务在飞)")
|
||||
var b10 = a10.runner().current_battle()
|
||||
var st10 := _adv_st()
|
||||
|
||||
@@ -87,6 +87,13 @@ func _ready() -> void:
|
||||
main.tune_panel.set_sliders(400, 200) # 高加成保 L1 可通关——L2 岔路选路段只能经冒险推进到达(单关直入口退役)
|
||||
var t1 := Time.get_ticks_msec()
|
||||
main._start_adventure_from_menu()
|
||||
await get_tree().process_frame
|
||||
# 停点前移批 2026-09-23:关卡开始 = 入口选路停点——真实按钮路径选入口候选进首战
|
||||
#(首格可点 AC 口径随之含入口选路一步:菜单点击 → 停点呈现 → pick → 棋盘安装)
|
||||
if main.route_overlay.visible:
|
||||
main.route_overlay.press_candidate(0)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
var t_entry := Time.get_ticks_msec() - t1
|
||||
# 性能 AC:进入战斗屏到首格可点 ≤500ms(棋盘 install 完成口径);
|
||||
# 场景实例化冷启动总时长(含全部脚本首载编译——引擎启动域,非 AC 口径)另列观测
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# 实现 GDD:design/ux/battle.md(场景级 headless 探针——四区布局实例化断言;entry 17②③)。
|
||||
# Date: 2026-09-12(战斗屏改造批扩展;基础 = 2026-09-11 首战棋盘探针——既有断言全保留)
|
||||
# 项目运行模式(autoload 在位)实例化 main.tscn,直接驱动 _start_adventure_from_menu()(完整冒险——唯一试玩入口),
|
||||
# 断言四区真实构建(棋盘/进度条/主角站桩/敌方站桩/AP 点阵/明细带/数据框;E 区道具面板已删除;
|
||||
# 2026-09-20 全站桩拍板——英雄卡/敌人卡断言随站桩改造批换装)。
|
||||
# 断言真实构建(棋盘/主角站桩/敌方站桩/AP 点阵/明细带/数据框;A 区进度条断言随 停点前移批 2026-09-23 退役;
|
||||
# E 区道具面板已删除;2026-09-20 全站桩拍板——英雄卡/敌人卡断言随站桩改造批换装)。
|
||||
# 运行:Godot_console.exe --headless --path . res://smoke/ui_probe.tscn
|
||||
extends Node
|
||||
|
||||
@@ -61,6 +61,17 @@ func _ready() -> void:
|
||||
main._start_adventure_from_menu()
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
# ---- 入口选路停点(停点前移批 2026-09-23:关卡开始即出节点图——level_started 后、首战前弹选路层;
|
||||
# 真实按钮路径 pick 入口单候选进首战)----
|
||||
if not main.route_overlay.visible:
|
||||
problems.append("关卡开始未弹入口选路停点(route_overlay 应可见)")
|
||||
elif main.runner == null or not main.runner.awaiting_choice() \
|
||||
or main.runner.next_candidate_ids().size() != 1:
|
||||
problems.append("入口停点状态失守(选路态 + 入口单候选)")
|
||||
else:
|
||||
main.route_overlay.press_candidate(0)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
# ---- 放弃入口·冒险模式可见 + 战斗中按下被拒(真实按钮路径——入口挂选路停点,战斗中拒绝为防御分支)----
|
||||
if main.route_overlay.abandon_btn == null or not main.route_overlay.abandon_btn.visible:
|
||||
problems.append("冒险模式放弃按钮未开放(选路停点入口在案)")
|
||||
@@ -69,13 +80,11 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if main.adventure == null or String(main.adventure.state) != "running":
|
||||
problems.append("首战中放弃未被拒(战斗域单事务在飞——state 应保持 running)")
|
||||
# ---- 既有断言(回归基线)----
|
||||
# ---- 既有断言(回归基线;A 区进度条断言随 停点前移批 2026-09-23 退役——节点链进度由关卡画面选路覆盖层承载)----
|
||||
if main.board_view._cells.is_empty():
|
||||
problems.append("棋盘格未生成(cells=0)")
|
||||
if main.board_view.board() == null:
|
||||
problems.append("board 未装载")
|
||||
if main.strip_view.get_child_count() < 2 * main.runner.nodes().size() - 1:
|
||||
problems.append("节点进度条未构建(%d 子节点)" % main.strip_view.get_child_count())
|
||||
if main.info_panel.hp_text().begins_with("HP —") or main.info_panel.hp_text().contains("—"):
|
||||
problems.append("C 区血量未显示(%s)" % main.info_panel.hp_text())
|
||||
if main.settlement == null or main.settlement.battle_result != "":
|
||||
@@ -183,9 +192,9 @@ func _ready() -> void:
|
||||
main.board_view.set_desaturated(true)
|
||||
main.board_view.set_desaturated(false)
|
||||
if problems.is_empty():
|
||||
print("[ui_probe] PASS — cells=%d board=%dx%d strip=%d hp='%s' enemies=%d ap_dots=%d" % [
|
||||
print("[ui_probe] PASS — cells=%d board=%dx%d hp='%s' enemies=%d ap_dots=%d" % [
|
||||
main.board_view._cells.size(), main.board_view.board().width, main.board_view.board().height,
|
||||
main.strip_view.get_child_count(), main.info_panel.hp_text(),
|
||||
main.info_panel.hp_text(),
|
||||
main.stage.enemy_box.get_child_count(), main.ap_bar._dots.get_child_count()])
|
||||
get_tree().quit(0)
|
||||
else:
|
||||
|
||||
@@ -64,6 +64,11 @@ func _ready() -> void:
|
||||
main._start_adventure_from_menu() # 完整冒险路径(唯一试玩入口;_start_single 按语义清零滑条 = 恒基线,不承载加成断言)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
# 停点前移批 2026-09-23:关卡开始 = 入口选路停点——真实按钮路径选入口候选进首战再读呈现快照
|
||||
if main.route_overlay.visible:
|
||||
main.route_overlay.press_candidate(0)
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
var hero: Dictionary = main.settlement.presentation_snapshot().hero
|
||||
if int(hero.get("atk", -1)) != boosted_atk or int(hero.get("max_hp", -1)) != boosted_hp:
|
||||
problems.append("战斗加成单次生效违例(atk=%s max_hp=%s,期望 %d/%d)" % [
|
||||
|
||||
Reference in new issue
Block a user