audit: 全屏UI审计(用户令返工)——实机十二屏窗口化截图(ui_audit_probe真实信号驱动)×demo v2.1纯净模式浏览器现截九屏;逐屏并排对比图九组+差距报告(底栏重设计草案头号待裁/D1D2量级坐实/结算仪式感/背景全局差距/标题屏主操作语义/E5爆破带demo紫带证据);零代码修改

This commit is contained in:
DKChan committed 2026-10-06 05:57:48 +08:00
1 parent a2b7c215ae
commit 34eb46038b
42 files changed
+153

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

+147
View File
@@ -0,0 +1,147 @@
# VERTICAL SLICE - NOT FOR PRODUCTION
# 全屏 UI 审计截图探针(2026-10-06 用户令——实机每一屏 vs demo v2.1 逐屏对比;shot_probe 十二屏扩展形)。
# 必须**窗口化**运行(真渲染面;headless 守卫同 shot_probe):
# Godot_console.exe --path . res://smoke/ui_audit_probe.tscn -- <输出目录>
# 覆盖 = demo 八映射屏(start/camp/settings/map/battle/bonus/shop/end 胜败两态)+ demo 无映射三屏
# (legend 图例/confirm 确认框/debug 调试浮窗)。真实信号路径驱动 + 合成面开窗(ui_struct_probe 同款
# 真实 open API+拟真数据);双帧 frame_post_draw 同步抓视口纹理。
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd")
const Narrator := preload("res://presentation/battle_narrator.gd")
var main: Node
var out_dir := ""
var _problems: Array = []
func _ready() -> void:
if DisplayServer.get_name() == "headless":
print("[ui_audit] FAIL — 本探针必须窗口化运行(headless 无渲染面)")
get_tree().quit(1)
return
var args := OS.get_cmdline_user_args()
out_dir = args[0] if args.size() >= 1 and args[0] != "" else "user://ui-audit"
DirAccess.make_dir_recursive_absolute(out_dir)
await get_tree().process_frame
main = load("res://presentation/main.tscn").instantiate()
add_child(main)
await get_tree().process_frame
ProbeUiUtil.isolate_save(main, "smoke_ui_audit", true, true, false)
await get_tree().process_frame
# 1 标题屏(启动态)
await _snap("1_start")
# 2 调试浮窗(P3 仅开始菜单可开——趁 _level_active=false 先截)
main._show_debug_overlay()
await _settle()
await _snap("9_debug")
main._close_debug_overlay()
await _settle()
# 3 设置
main._open_settings()
await _settle()
await _snap("3_settings")
main._on_settings_closed()
await _settle()
# 4 营地
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "contains")
if campbtn != null:
campbtn.pressed.emit()
await _settle()
await _snap("2_camp")
var close_btn: Button = ProbeUiUtil.find_button(main.camp_overlay, "关闭营地", "contains")
if close_btn != null:
close_btn.pressed.emit()
await _settle()
# 5 关卡地图(开始冒险→停点出图)
var lvbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "开始冒险", "contains")
if lvbtn != null:
lvbtn.pressed.emit()
for i in 4:
await get_tree().process_frame
await _settle()
await _snap("4_map")
# 6 战斗(真实选路提交)
if main.level_screen != null and main.level_screen.visible:
main.level_screen.press_candidate(0)
for i in 10:
await get_tree().process_frame
await _settle()
await _snap("5_battle")
# 7 战斗结算·胜利(真实签名的拟真载荷——main.gd:697 同序)
main._end_overlay.open_victory(Narrator.battle_end_text("victory", true), "返回",
main.board_view.get_global_rect(), "战利品 GP +5 · 合计 24",
"钥石 · 累计 27", "本关加成:攻击 +1", 5, 24)
await _settle()
await _snap("8_end_victory")
main._end_overlay.close()
await _settle()
# 8 战斗结算·失败
main._end_overlay.open_defeat(Narrator.battle_end_text("defeat", false), "返回",
main.board_view.get_global_rect())
await _settle()
await _snap("8_end_defeat")
main._end_overlay.close()
await _settle()
# 9 三选一(拟真三卡)
main.curio_overlay.open_pick(Narrator.node_curio_header(), [
{"id": "heal_rare", "text": "回血\n恢复 3 点"},
{"id": "blast_rare", "text": "爆裂轰击\n下一击 +5"},
{"id": "pierce_rare", "text": "穿甲\n无视护甲"},
])
await _settle()
await _snap("6_bonus")
main.curio_overlay.visible = false
await _settle()
# 10 商店(买前态)
main.shop_overlay.open_shop([
{"product_id": "attack", "display_name": "攻击强化", "attr": "atk", "flat_value": 1, "price": 12, "purchased": 0},
{"product_id": "max_hp", "display_name": "生命强化", "attr": "hp", "flat_value": 3, "price": 12, "purchased": 0},
{"product_id": "armor", "display_name": "护甲强化", "attr": "armor", "flat_value": 1, "price": 15, "purchased": 0},
], 27)
await _settle()
await _snap("7_shop")
main.shop_overlay.visible = false
await _settle()
# 11 图例
main.legend_overlay.open()
await _settle()
await _snap("10_legend")
main.legend_overlay.close()
await _settle()
# 12 确认框(放弃二次确认实文案)
main.confirm_dialog.open("放弃冒险", "确认放弃本次冒险?已入账钥匙与 GP 将结算保留")
await _settle()
await _snap("11_confirm")
main.confirm_dialog.close()
await _settle()
for s in ["1_start", "9_debug", "3_settings", "2_camp", "4_map", "5_battle",
"8_end_victory", "8_end_defeat", "6_bonus", "7_shop", "10_legend", "11_confirm"]:
var p := out_dir.path_join("real_%s.png" % s)
if not FileAccess.file_exists(p):
_problems.append("截图缺失: %s" % s)
else:
var fa := FileAccess.open(p, FileAccess.READ)
if fa == null or fa.get_length() < 1000:
_problems.append("截图疑似空文件: %s" % s)
print("[ui_audit] 完成 out=%s 问题=%d %s" % [out_dir, _problems.size(), str(_problems)])
get_tree().quit(1 if _problems.size() > 0 else 0)
func _settle() -> void:
for i in 3:
await get_tree().process_frame
await RenderingServer.frame_post_draw
func _snap(key: String) -> void:
await RenderingServer.frame_post_draw
await RenderingServer.frame_post_draw
var img: Image = get_viewport().get_texture().get_image()
if img == null:
_problems.append("视口纹理为空: %s" % key)
return
img.save_png(out_dir.path_join("real_%s.png" % key))
print("[ui_audit] saved %s (%dx%d)" % [key, img.get_width(), img.get_height()])
+6
View File
@@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3]
[ext_resource type="Script" path="res://smoke/ui_audit_probe.gd" id="1"]
[node name="UIAuditProbe" type="Node"]
script = ExtResource("1")