Files
aetherbound-guild/runtime/tests/dev1/title_responsive_layout_test.gd
T
wushenghua c5bd5bf05b fix: replace Title with seamless v002 master
Supersede the composited v001 Title artwork with the Owner-approved single-frame v002 master, align runtime text to its command plaques, and remove the extra background image from responsive composition.
2026-08-19 14:38:19 +08:00

80 lines
3.7 KiB
GDScript

extends SceneTree
const EntryShell = preload("res://entry/entry_shell.gd")
const SettingsStore = preload("res://entry/settings_store.gd")
const DESIGN_ASPECT := 16.0 / 9.0
const SIZES := [Vector2i(800, 500), Vector2i(960, 540), Vector2i(1280, 600)]
var failures: Array[String] = []
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
var viewport := SubViewport.new()
viewport.size = SIZES[0]
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
root.add_child(viewport)
var shell := EntryShell.new()
shell.auto_start = false
viewport.add_child(shell)
await _frames(3)
var settings := SettingsStore.new().defaults()
settings.setup_completed = true
settings.locale = "zh_CN"
settings.text_scale = 1.3
shell.settings = settings
shell.setup_draft = settings.duplicate(true)
shell.show_title()
await _frames(4)
for viewport_size in SIZES:
viewport.size = viewport_size
await _frames(3)
_verify_layout(shell, viewport_size)
if failures.is_empty():
print("ABG_DEV1_TITLE_RESPONSIVE_OK sizes=800x500,960x540,1280x600 canvas=16:9 centered world=full controls=4 resize=true")
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func _verify_layout(shell: Control, viewport_size: Vector2i) -> void:
var bounds := Rect2(Vector2.ZERO, Vector2(viewport_size))
var world := shell.find_child("TitleMasterWorldExtension", true, false) as Control
var canvas := shell.find_child("TitleSafeArea", true, false) as Control
var composite := shell.find_child("TitleMasterComposite", true, false) as TextureRect
expect(world != null and canvas != null and composite != null, "%dx%d Title composition layers exist" % [viewport_size.x, viewport_size.y])
if world == null or canvas == null or composite == null:
return
var canvas_rect := canvas.get_global_rect()
expect(bounds.encloses(canvas_rect), "%dx%d Title canvas is fully visible" % [viewport_size.x, viewport_size.y])
expect(is_equal_approx(canvas_rect.size.x / canvas_rect.size.y, DESIGN_ASPECT), "%dx%d Title canvas preserves 16:9" % [viewport_size.x, viewport_size.y])
expect(canvas_rect.get_center().is_equal_approx(bounds.get_center()), "%dx%d Title canvas is centered" % [viewport_size.x, viewport_size.y])
expect(world.get_global_rect().is_equal_approx(bounds), "%dx%d Title world fills the viewport" % [viewport_size.x, viewport_size.y])
expect(composite.get_global_rect().is_equal_approx(canvas_rect), "%dx%d Title composite shares the design canvas" % [viewport_size.x, viewport_size.y])
for node_name in ["TitleNewGame", "TitleContinue", "TitleSettings", "TitleCredits"]:
var control := shell.find_child(node_name, true, false) as Control
expect(control != null and canvas_rect.encloses(control.get_global_rect()), "%dx%d %s remains inside the Title canvas" % [viewport_size.x, viewport_size.y, node_name])
var viewport_aspect := float(viewport_size.x) / float(viewport_size.y)
if viewport_aspect < DESIGN_ASPECT:
expect(is_equal_approx(canvas_rect.size.x, float(viewport_size.x)) and canvas_rect.position.y > 0.0, "%dx%d uses vertical World extension" % [viewport_size.x, viewport_size.y])
elif is_equal_approx(viewport_aspect, DESIGN_ASPECT):
expect(canvas_rect.is_equal_approx(bounds), "%dx%d uses the complete device frame" % [viewport_size.x, viewport_size.y])
else:
expect(is_equal_approx(canvas_rect.size.y, float(viewport_size.y)) and canvas_rect.position.x > 0.0, "%dx%d uses horizontal World extension" % [viewport_size.x, viewport_size.y])
func _frames(count: int) -> void:
for frame in range(count):
await process_frame
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("DEV-1 Title responsive: %s" % message)