Files
gplan-2/game/smoke/shot_probe.gd
T

101 lines
4.3 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VERTICAL SLICE - NOT FOR PRODUCTION
# 整屏截图探针(迭代 9 卡⑰a 2026-09-30——呈现层测试分级 B 档基建:四屏视口截图程序化产出)。
# 必须**窗口化**运行(真渲染设备——headless 无渲染面,get_image 得到空纹理):
# Godot_console.exe --path . res://smoke/shot_probe.tscn -- <输出目录>
# 流程 = 真实按钮信号路径驱动(ui_click_probe 同款;存档/设置/元进度三面换注隔离档——禁碰真实档,
# 坑册「断点写盘随 save_manager 引用走」教训同款覆盖):菜单(启动态)→ 营地(campbtn)→
# 关卡画面(lvbtn→停点出图)→ 战斗(level_screen.press_candidate(0) 真实选路提交)。
# 每屏双帧 + frame_post_draw 同步后抓 get_viewport().get_texture(),PNG 落输出目录;
# 最小自检 = 四件存在且非零字节(像素方差断言归 tools/shot_checker.py——B 档骨架分工)。
extends Node
var main
var out_dir := ""
var _problems: Array = []
func _ready() -> void:
var args := OS.get_cmdline_user_args()
out_dir = args[0] if args.size() >= 1 and args[0] != "" else "user://qa-screens"
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
# ── 存档/元进度/设置三面隔离(ui_click_probe 同款——真档零污染) ──
for p0 in ["user://smoke_shot_probe.json", "user://smoke_shot_probe.json.tmp",
"user://smoke_shot_probe_settings.cfg"]:
if FileAccess.file_exists(p0):
DirAccess.remove_absolute(p0)
var iso_c = load("res://core/save_manager.gd").new("user://smoke_shot_probe.json")
iso_c.load_from_disk()
main.save_manager = iso_c
main.meta = load("res://core/meta_progression.gd").new(main.db, iso_c)
main.settings_store = load("res://presentation/settings_store.gd").new("user://smoke_shot_probe_settings.cfg")
await get_tree().process_frame
# ① 菜单(启动态)
await _snap("menu")
# ② 营地
var campbtn: Button = _find_button_by_prefix(main._start_overlay, "营地")
if campbtn == null:
_problems.append("营地入口缺失(开始层 campbtn)")
else:
campbtn.pressed.emit()
await get_tree().process_frame
await _snap("camp")
var close_btn: Button = _find_button_by_prefix(main.camp_overlay, "关闭营地")
if close_btn != null:
close_btn.pressed.emit()
await get_tree().process_frame
# ③ 关卡画面(开始冒险→停点出图——冒险开始即出图,停点前移批语义)
var lvbtn: Button = _find_button_by_prefix(main._start_overlay, "开始冒险")
if lvbtn == null:
_problems.append("开始冒险按钮缺失(开始层 lvbtn)")
else:
lvbtn.pressed.emit()
for i in 4:
await get_tree().process_frame
await _snap("level")
# ④ 战斗(节点一——真实选路提交路径 press_candidate,ui_click_probe :199 同款)
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 _snap("battle")
else:
_problems.append("关卡画面未出现(lvbtn 路径)")
# ── 最小自检:四件存在且非零字节 ──
for s in ["menu", "camp", "level", "battle"]:
var p := out_dir.path_join("shot_%s.png" % s)
if not FileAccess.file_exists(p):
_problems.append("截图缺失: %s" % p)
else:
var fa := FileAccess.open(p, FileAccess.READ)
if fa == null or fa.get_length() < 1000:
_problems.append("截图疑似空文件: %s" % p)
print("[shot_probe] 完成 out=%s 问题=%d %s" % [out_dir, _problems.size(), str(_problems)])
get_tree().quit(1 if _problems.size() > 0 else 0)
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("shot_%s.png" % key))
print("[shot_probe] saved %s (%dx%d)" % [key, img.get_width(), img.get_height()])
func _find_button_by_prefix(root: Node, prefix: String) -> Button:
if root == null:
return null
if root is Button and String(root.text).contains(prefix):
return root
for c in root.get_children():
var r := _find_button_by_prefix(c, prefix)
if r != null:
return r
return null