Add headless regression tests for Phase 4b features
- Implement test for popup anchor behavior in rule-builder menus to ensure consistent anchor positioning during menu transitions. - Create tests for stage logic, including mode transitions, toolbar visibility, and status bar updates. - Add terrain drag-painting tests to verify correct block placement behavior and conflict handling. - Introduce walk waypoint tests to check for arrival conditions and position stability after navigation.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
class_name StickmanThumbnail
|
||||
extends Node
|
||||
|
||||
const STICKMAN_FACTORY := preload("res://scripts/stickman_factory.gd")
|
||||
const STAGE_SPAWNER := preload("res://scripts/stage_spawner.gd")
|
||||
|
||||
const SIZE := Vector2i(200, 200)
|
||||
|
||||
var _viewport: SubViewport
|
||||
var _world: Node2D
|
||||
var _camera: Camera2D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_viewport = SubViewport.new()
|
||||
_viewport.size = SIZE
|
||||
_viewport.transparent_bg = true
|
||||
_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
||||
add_child(_viewport)
|
||||
_world = Node2D.new()
|
||||
_viewport.add_child(_world)
|
||||
_camera = Camera2D.new()
|
||||
_camera.enabled = true
|
||||
_viewport.add_child(_camera)
|
||||
_camera.make_current()
|
||||
|
||||
|
||||
func render(stk_data: Dictionary) -> Texture2D:
|
||||
_clear_world()
|
||||
var rig: Node2D = STICKMAN_FACTORY.spawn_from_data(stk_data)
|
||||
if rig == null:
|
||||
return null
|
||||
_world.add_child(rig)
|
||||
rig.position = Vector2.ZERO
|
||||
var bbox := STAGE_SPAWNER.get_world_aabb(rig)
|
||||
if not bbox.has_area() or bbox.size.x < 1.0 or bbox.size.y < 1.0:
|
||||
bbox = Rect2(Vector2(-60, -500), Vector2(120, 500))
|
||||
_frame_camera(bbox)
|
||||
await RenderingServer.frame_post_draw
|
||||
await RenderingServer.frame_post_draw
|
||||
var tex := _viewport.get_texture()
|
||||
rig.queue_free()
|
||||
if tex == null:
|
||||
return null
|
||||
var img := tex.get_image()
|
||||
if _is_blank(img):
|
||||
return null
|
||||
return ImageTexture.create_from_image(img)
|
||||
|
||||
|
||||
func _clear_world() -> void:
|
||||
for child: Node in _world.get_children():
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func _frame_camera(bbox: Rect2) -> void:
|
||||
var margin := 12.0
|
||||
var fit := minf((SIZE.x - margin * 2.0) / bbox.size.x, (SIZE.y - margin * 2.0) / bbox.size.y)
|
||||
_camera.position = bbox.get_center()
|
||||
_camera.zoom = Vector2(maxf(fit, 0.05), maxf(fit, 0.05))
|
||||
|
||||
|
||||
func _is_blank(img: Image) -> bool:
|
||||
if img == null or img.is_empty():
|
||||
return true
|
||||
var used := img.get_used_rect()
|
||||
if used.size.x <= 0 or used.size.y <= 0:
|
||||
return true
|
||||
for y: int in range(used.position.y, used.end.y):
|
||||
for x: int in range(used.position.x, used.end.x):
|
||||
if img.get_pixel(x, y).a > 0.0:
|
||||
return false
|
||||
return true
|
||||
Reference in New Issue
Block a user