feat(迭代28 T4): 渲染面内容断言三件(探针自检+墨色判据+启动态菜单 golden)

①shot_probe.gd 两条自检进 _problems:boot 态顶层可见层=start_overlay(内容层树遍历——屏壳容器不当候选,camp 壳透明实证);菜单标题/副标题 label is_visible_in_tree 且 rect 落屏内;隔离档 refresh_resume 开=菜单截图不依赖真实档断点态。②shot_checker.py 增 F 字在判据:菜单文字框与中位灰度差>60 像素占比带 [2%,55%](极性无关——亮字暗底同判;实测标题 13.07%/副标题 11.47% 定 provisional 阈值;对比度只判反差不判字在的缺口由此补)。③启动态菜单 golden:帧差前置验 0.0000%/max_diff=0(光柱静态贴片零动画);golden_baseline_refresh.sh 扩 --menu 模式(shot_probe 取材→game/tests/golden/menu_boot.png,字体+按钮石纹素材守卫);render_gate.sh 补菜单 golden 对比段(素材缺位 SKIP 同 Q5 口径)。闸=render_gate 全绿(探针问题=0+checker A-D/F 全过+棋盘 golden 0.00%×3+菜单 golden 0.00%)。注:本机 render_gate 需 gamedev venv Python 前置 PATH(闸机脚本调 python(PIL),本机默认 python 无 PIL——用户侧环境自带)
This commit is contained in:
DKChan committed 2026-10-15 07:28:38 +08:00
1 parent 77075e6e7a
commit 67342c690e
5 files changed
+127 -11

No files matched your search

+37 -3
View File
@@ -36,7 +36,9 @@ func _ready() -> void:
add_child(main)
await get_tree().process_frame
# ── 存档/元进度/设置三面隔离(ui_click_probe 同款——真档零污染;历史语义 = contains 寻址) ──
ProbeUiUtil.isolate_save(main, "smoke_shot_probe", false, true, false)
# 迭代 28 T4:refresh_resume 开——续玩钮按隔离档(无断点)定基,菜单截图/golden 基线不依赖
# 真实档断点态(boot 关系由冒烟 _smoke_boot_chain V2d 断,此处只保截图确定性)
ProbeUiUtil.isolate_save(main, "smoke_shot_probe", false, true, true)
# 隔离档即时应用(迭代 19 卡① T1——main 装配已按真实设置恢复过窗口态〔本机实测:真实档
# fullscreen=true 时窗口进全屏,视口纹理 2304x1440≠1280 基准档,checker 尺寸/取样全盘失真〕;
# apply 隔离档出厂默认=窗口化 1280x800,恢复本探针设计前提。探针侧环境修正,零运行时改动)
@@ -44,8 +46,40 @@ func _ready() -> void:
await get_tree().process_frame
# ① 菜单(启动态)——meta 锚经 S1 裁后换代(2026-10-08 用户裁:副标题锚改认现行文案;
# 帮助文腿整个退役——载体玩法速览牌 2026-10-06 用户令退役,checker 对应断言段同撤)
_meta["menu_sub"] = ProbeUiUtil.label_rect(main._start_overlay, "扫雷的因")
_meta["menu_title"] = ProbeUiUtil.label_rect(main._start_overlay, "Dungeon Sweeper")
# 自检一(迭代 28 T4):boot 态顶层可见全屏层=start_overlay(内容层树遍历——屏壳是容器不当候选:
# camp 壳 boot 态 vis=true 但成员恒隐,裸树遍历自顶向下会先命中透明壳)
var top: Node = null
var top_rx := -1
var top_ry := -1
for c: Node in [main._start_overlay, main._battle_root, main._inter_overlay,
main.legend_overlay, main.node_overlay, main.level_screen, main.curio_overlay,
main._end_overlay, main.shop_overlay, main.camp_overlay, main.settings_overlay,
main.status_panel, main.career_overlay, main.confirm_dialog, main.debug_overlay]:
if c == null or not (c is CanvasItem) or not (c as CanvasItem).visible:
continue
var rx: int = c.get_parent().get_index()
var ry: int = c.get_index()
if top == null or rx > top_rx or (rx == top_rx and ry > top_ry):
top = c
top_rx = rx
top_ry = ry
if top != main._start_overlay:
_problems.append("boot 态顶层可见层≠start_overlay(实测 %s——菜单被埋)〔装配生命批 V4〕"
% (top.name if top != null else "null"))
# 自检二(迭代 28 T4):菜单标题/副标题 label 必须 is_visible_in_tree 且 rect 落屏内
#(对比度只判反差不判「字在」——本条+checker 墨色占比共同补内容判据)
var vp := get_viewport().get_visible_rect()
for pair in [["menu_title", "Dungeon Sweeper"], ["menu_sub", "扫雷的因"]]:
var lbl: Label = ProbeUiUtil.find_label(main._start_overlay, String(pair[1]))
if lbl == null:
_problems.append("菜单文字缺失: %s(find_label 零命中)〔装配生命批 V4〕" % String(pair[1]))
continue
if not lbl.is_visible_in_tree():
_problems.append("菜单文字不可见: %s(is_visible_in_tree=false——层被埋或隐藏)〔装配生命批 V4〕" % String(pair[1]))
var gr: Rect2 = lbl.get_global_rect()
if not vp.encloses(gr):
_problems.append("菜单文字 rect 越出视口: %s(%s ⊄ %s)〔装配生命批 V4〕" % [String(pair[1]), str(gr), str(vp)])
_meta[String(pair[0])] = ProbeUiUtil.label_rect(main._start_overlay, String(pair[1]))
await _snap("menu")
# ①b 设置面(迭代 19 卡① T1 扩屏——settingsbtn 真实信号路径,开合同款真实钮)
var setbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "设置", "prefix")
Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB