10 gdUnit4 tests verifying camera behavior: SimBridge test mode connection, snapshot pipeline, player position extraction, camera anchor in _ready(), smoothing disable/re-enable cycle, camera tracking across frames, and player movement following. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
146 lines
4.4 KiB
GDScript
146 lines
4.4 KiB
GDScript
## Tests for camera anchor behavior — the camera must show the player's
|
|
## position from the very first rendered frame, with no visible drift from (0,0).
|
|
##
|
|
## These tests verify the full pipeline: SimBridge → GameState → Camera2D.
|
|
## The player starts at (10,10) in test mode, so the expected camera position
|
|
## is (10,10) * TILE_SIZE = (320, 320).
|
|
class_name TestCameraAnchor
|
|
extends GdUnitTestSuite
|
|
|
|
const EXPECTED_PLAYER_POS := Vector2(10, 10)
|
|
const EXPECTED_CAMERA_POS := Vector2(320, 320) # 10 * 32, 10 * 32
|
|
|
|
var _instance: Node = null
|
|
|
|
|
|
func before_test() -> void:
|
|
SimBridge.reset_test_state()
|
|
GameState.current_tick = 0
|
|
GameState.player_position = Vector2.ZERO
|
|
GameState.visible_entities = []
|
|
GameState.visible_tiles = []
|
|
GameState.visible_positions = {}
|
|
GameState.current_monologue = null
|
|
GameState.current_dialogue = null
|
|
|
|
|
|
func after_test() -> void:
|
|
if _instance and is_instance_valid(_instance):
|
|
_instance.queue_free()
|
|
_instance = null
|
|
|
|
|
|
# --- Pipeline precondition tests ---
|
|
|
|
func test_simbridge_connected_in_test_mode() -> void:
|
|
SimBridge.state = SimBridge.ConnectionState.DISCONNECTED
|
|
SimBridge.connect_to_sim()
|
|
assert_that(SimBridge.state).is_equal(SimBridge.ConnectionState.CONNECTED)
|
|
|
|
|
|
func test_poll_snapshot_returns_data_when_connected() -> void:
|
|
SimBridge.connect_to_sim()
|
|
var snapshot: Variant = SimBridge.poll_snapshot()
|
|
assert_that(snapshot).is_not_null()
|
|
assert_that(snapshot is Dictionary).is_true()
|
|
|
|
|
|
func test_snapshot_has_player_at_10_10() -> void:
|
|
var snap := SimBridge._test_snapshot()
|
|
var player_x: float = -1.0
|
|
var player_y: float = -1.0
|
|
for entity in snap.entities:
|
|
if entity.kind.variant == "Player":
|
|
player_x = entity.x
|
|
player_y = entity.y
|
|
break
|
|
assert_that(player_x).is_equal(10.0)
|
|
assert_that(player_y).is_equal(10.0)
|
|
|
|
|
|
func test_apply_snapshot_sets_player_position() -> void:
|
|
var snap := SimBridge._test_snapshot()
|
|
GameState.apply_snapshot(snap)
|
|
assert_that(GameState.player_position).is_equal(EXPECTED_PLAYER_POS)
|
|
|
|
|
|
# --- Camera anchor after _ready() ---
|
|
|
|
func test_camera_position_after_ready() -> void:
|
|
var scene := load("res://scenes/main.tscn")
|
|
_instance = scene.instantiate()
|
|
auto_free(_instance)
|
|
add_child(_instance)
|
|
|
|
var camera: Camera2D = _instance.get_node("Camera2D")
|
|
assert_that(camera.global_position).is_equal(EXPECTED_CAMERA_POS)
|
|
|
|
|
|
func test_camera_anchored_flag_after_ready() -> void:
|
|
var scene := load("res://scenes/main.tscn")
|
|
_instance = scene.instantiate()
|
|
auto_free(_instance)
|
|
add_child(_instance)
|
|
|
|
assert_that(_instance._camera_anchored).is_true()
|
|
|
|
|
|
func test_camera_smoothing_off_after_ready() -> void:
|
|
# Camera smoothing must be disabled during init to prevent lerp from (0,0).
|
|
# If this test fails, the camera will visibly drift from origin to player.
|
|
var scene := load("res://scenes/main.tscn")
|
|
_instance = scene.instantiate()
|
|
auto_free(_instance)
|
|
add_child(_instance)
|
|
|
|
var camera: Camera2D = _instance.get_node("Camera2D")
|
|
assert_that(camera.position_smoothing_enabled).is_false()
|
|
|
|
|
|
# --- Camera behavior across frames ---
|
|
|
|
func test_camera_tracks_player_after_process() -> void:
|
|
var scene := load("res://scenes/main.tscn")
|
|
_instance = scene.instantiate()
|
|
auto_free(_instance)
|
|
add_child(_instance)
|
|
|
|
# Simulate one game frame
|
|
_instance._process(0.016)
|
|
|
|
var camera: Camera2D = _instance.get_node("Camera2D")
|
|
var expected := GameState.player_position * Constants.TILE_SIZE
|
|
assert_that(camera.global_position).is_equal(expected)
|
|
|
|
|
|
func test_camera_smoothing_reenabled_after_process() -> void:
|
|
# After the first anchored frame, smoothing should be back on for gameplay.
|
|
var scene := load("res://scenes/main.tscn")
|
|
_instance = scene.instantiate()
|
|
auto_free(_instance)
|
|
add_child(_instance)
|
|
|
|
_instance._process(0.016)
|
|
|
|
var camera: Camera2D = _instance.get_node("Camera2D")
|
|
assert_that(camera.position_smoothing_enabled).is_true()
|
|
|
|
|
|
func test_camera_follows_player_movement() -> void:
|
|
var scene := load("res://scenes/main.tscn")
|
|
_instance = scene.instantiate()
|
|
auto_free(_instance)
|
|
add_child(_instance)
|
|
|
|
var camera: Camera2D = _instance.get_node("Camera2D")
|
|
var initial_pos := camera.global_position
|
|
|
|
# Move player north via SimBridge test mode
|
|
SimBridge._test_input_queue.append("MoveNorth")
|
|
_instance._process(0.016)
|
|
|
|
# Camera should have moved with the player
|
|
assert_that(camera.global_position.y < initial_pos.y).is_true()
|
|
assert_that(camera.global_position).is_equal(
|
|
GameState.player_position * Constants.TILE_SIZE)
|