Files
gplan-2/game/smoke/ui_layout_probe.gd
T
DKChan 5f9d8e7b77 chore(代码卫生): 文件头零工作日志红线落文+全仓头注变更叙事清偿(2026-10-15 用户令)
- CLAUDE.md 硬性红线新增「文件头零工作日志」;code-conventions.md 新增 §1.4.1(含反面案例)
- 全仓 .gd 文件头注清偿:删除全部带日期条目、批次叙事段与迁移退役叙述,保留并改写为
  现在时的职责、接口契约、GDD 锚内容(main.gd 头注 42→31 行、save_manager.gd 49→45 行)
- 纯注释改动零行为变更,按用户令免测试免冒烟
2026-10-15 04:08:38 +08:00

114 lines
5.6 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
# Date: 2026-09-13(四区布局诊断探针——"内容未满幅/棋盘底裁切"回归定位:打印窗口/视口/四区实际矩形
# 与最小尺寸、展开旗标,对照 battle.md §Layout 1280×800 基座规格)
# 断言件(1280/1920 两档):
# ①基座 1280×800(battle.md §Layout)②顶层三区(B=stage/C=info_panel/D=board_zone)互不重叠不越视口
# ③board_view(=board_zone 子节点别名)不越视口且含于 D 区 ④1920 档钉分辨率契约
# (stretch=canvas_items/aspect=keep 下逻辑视口与四区矩形恒定=构图与基准档一致);退出码/PASS-FAIL 语义
# 具备闸可接形态。原诊断打印面全保留。
# 运行:Godot_console.exe --headless --path . res://smoke/ui_layout_probe.tscn
extends Node
const ProbeUiUtil := preload("res://smoke/probe_ui_util.gd") # T6 收口:隔离样板单点
func _ready() -> void:
await get_tree().process_frame # autoload 就绪
var main: Node = load("res://presentation/main.tscn").instantiate()
add_child(main)
await get_tree().process_frame
# 存档隔离(迭代 8 卡①②——停点断点写盘随 main.save_manager;探针禁碰真实档,同族探针隔离纪律;
# isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退)
ProbeUiUtil.isolate_save(main, "smoke_layout_probe_save", true, false, true)
main.debug_overlay.seed_edit.text = "42" # 种子钉死(迭代 18 卡⑦审计🔴——种子框默认改空后空框=非首局随机,探针确定性禁依赖默认分支)
main._start_adventure_from_menu()
for i in range(3):
await get_tree().process_frame
var win := get_window()
print("window.size=%s pos=%s mode=%s" % [win.size, win.position, win.mode])
print("viewport.visible_rect=%s" % get_viewport().get_visible_rect())
print("main.size=%s" % main.size)
for c in main.get_children():
if c is Control:
_dump_ctrl(c, 0)
var zones := {
"board_zone": main.board_zone, "board_view": main.board_view,
"info_panel": main.info_panel,
"stage": main.stage,
}
for k in zones:
var ctl: Control = zones[k]
if ctl == null:
print("%s = null" % k)
continue
print("%-16s pos=%s size=%s min=%s hflag=%d vflag=%d" % [k, ctl.position, ctl.size,
ctl.custom_minimum_size, ctl.size_flags_horizontal, ctl.size_flags_vertical])
var root_box: Control = main._adventure_screen.battle_root # 迭代 27 T1——屏壳化后战斗四区根迁冒险屏壳(序数寻址漂移改名寻址)
print("four-zone root: anchors=(%s,%s)-(%s,%s) offsets=(%s,%s,%s,%s) size=%s" % [
root_box.anchor_left, root_box.anchor_top, root_box.anchor_right, root_box.anchor_bottom,
root_box.offset_left, root_box.offset_top, root_box.offset_right, root_box.offset_bottom, root_box.size])
print("board_view cell_size=%s board=%s" % [main.board_view.get("cell_size"), main.board_view.board()])
# ── 最小布局断言(迭代 19 卡① T5——1280/1920 两档;语义见头注) ──
var problems: PackedStringArray = []
var vr: Rect2 = get_viewport().get_visible_rect()
if vr.size != Vector2(1280, 800):
problems.append("基座视口 %s ≠ 1280x800(battle.md §Layout)" % vr.size)
var azones := {"stage": main.stage, "info_panel": main.info_panel, "board_zone": main.board_zone}
var arects := {}
for k in azones:
var actl: Control = azones[k]
if actl == null:
problems.append("%s=null" % k)
continue
var ar := Rect2(actl.global_position, actl.size)
arects[k] = ar
if ar.size.x <= 0.0 or ar.size.y <= 0.0:
problems.append("%s 零尺寸 %s" % [k, ar.size])
elif not vr.encloses(ar):
problems.append("%s 越视口 %s ⊄ %s" % [k, ar, vr])
var bvc: Control = main.board_view
if bvc == null:
problems.append("board_view=null")
else:
var br := Rect2(bvc.global_position, bvc.size)
if not vr.encloses(br):
problems.append("board_view 越视口 %s ⊄ %s" % [br, vr])
if arects.has("board_zone") and not arects["board_zone"].encloses(br):
problems.append("board_view 越出 board_zone(%s ⊄ %s)" % [br, arects["board_zone"]])
var akeys := arects.keys()
for i in range(akeys.size()):
for j in range(i + 1, akeys.size()):
if arects[akeys[i]].intersects(arects[akeys[j]]):
problems.append("顶层区重叠 %s×%s(%s ∩ %s)" % [akeys[i], akeys[j], arects[akeys[i]], arects[akeys[j]]])
# 1920 档(Q4 注记对应面:单档 1280 闸+本两档断言钉 1920 构图恒等——分辨率维度不重复建闸)
get_window().size = Vector2i(1920, 1080)
for i in range(4):
await get_tree().process_frame
var vr2: Rect2 = get_viewport().get_visible_rect()
if vr2 != vr:
problems.append("1920 档逻辑视口漂移 %s ≠ %s(案甲:stretch 基座恒定)" % [vr2, vr])
for k in azones:
var actl2: Control = azones[k]
if actl2 == null:
continue
var ar2 := Rect2(actl2.global_position, actl2.size)
if arects.has(k) and ar2 != arects[k]:
problems.append("1920 档 %s 矩形漂移 %s ≠ %s(案甲:构图与基准档一致)" % [k, ar2, arects[k]])
if problems.is_empty():
print("[layout_probe] PASS — 1280/1920 两档全过(基座1280x800/顶层三区互斥不越界/board_view含于D区/案甲构图恒定)")
get_tree().quit(0)
else:
for p in problems:
print("[layout_probe] FAIL — " + p)
print("[layout_probe] FAIL — %d 项断言未过" % problems.size())
get_tree().quit(1)
func _dump_ctrl(c: Control, depth: int) -> void:
var ind := " ".repeat(depth)
print("%s%s pos=%s size=%s min=%s" % [ind, c.name, c.position, c.size, c.custom_minimum_size])
for ch in c.get_children():
if ch is Control:
_dump_ctrl(ch, depth + 1)