Files
whale-town/tests/test_character_controller.gd
2025-12-05 19:00:14 +08:00

207 lines
5.4 KiB
GDScript

extends Node
## 角色控制器测试
## Feature: godot-ai-town-game, Property 4: 碰撞检测
const TEST_ITERATIONS = 100
func _ready():
print("\n=== CharacterController Tests ===")
test_property_collision_detection()
test_property_position_sync()
test_property_movement_ability()
print("=== All CharacterController tests completed ===\n")
## Feature: godot-ai-town-game, Property 4: 碰撞检测
func test_property_collision_detection():
"""
属性测试:碰撞检测
对于任意角色和障碍物,当角色尝试移动到障碍物位置时,
系统应该阻止该移动,角色位置保持不变
"""
print("\n[Property Test] Collision Detection")
var passed = 0
var failed = 0
for i in range(TEST_ITERATIONS):
# 创建测试场景
var character = CharacterController.new()
var obstacle = StaticBody2D.new()
var obstacle_shape = CollisionShape2D.new()
var shape = RectangleShape2D.new()
shape.size = Vector2(50, 50)
obstacle_shape.shape = shape
obstacle.add_child(obstacle_shape)
# 设置碰撞层
obstacle.collision_layer = 1 # 墙壁层
# 添加到场景树
add_child(character)
add_child(obstacle)
# 设置初始位置
character.global_position = Vector2(0, 0)
obstacle.global_position = Vector2(100, 0)
# 等待物理帧
await get_tree().physics_frame
var initial_pos = character.global_position
# 尝试向障碍物方向移动
character.move_to(Vector2(1, 0)) # 向右移动
# 等待几帧让移动发生
for j in range(10):
await get_tree().physics_frame
# 停止移动
character.move_to(Vector2.ZERO)
await get_tree().physics_frame
var final_pos = character.global_position
# 验证:角色应该移动了,但不应该穿过障碍物
var obstacle_distance = final_pos.distance_to(obstacle.global_position)
# 角色应该被阻挡在障碍物前面
if obstacle_distance > 25: # 障碍物半径 + 角色半径
passed += 1
else:
failed += 1
print(" FAILED iteration ", i + 1)
print(" Character penetrated obstacle")
print(" Distance to obstacle: ", obstacle_distance)
# 清理
character.queue_free()
obstacle.queue_free()
await get_tree().process_frame
print(" Result: ", passed, "/", TEST_ITERATIONS, " passed")
if failed > 0:
print(" ❌ FAILED: ", failed, " iterations failed")
else:
print(" ✅ PASSED: All iterations successful")
## Feature: godot-ai-town-game, Property 3: 位置更新同步
func test_property_position_sync():
"""
属性测试:位置更新同步
对于任意角色的移动操作,执行移动后角色的位置坐标应该被更新
"""
print("\n[Property Test] Position Update Sync")
var passed = 0
var failed = 0
for i in range(TEST_ITERATIONS):
var character = CharacterController.new()
add_child(character)
await get_tree().physics_frame
# 设置随机目标位置
var target_pos = Vector2(
randf_range(-500, 500),
randf_range(-500, 500)
)
var signal_data = {
"position_updated": false,
"updated_position": Vector2.ZERO
}
# 连接位置更新信号
var callback = func(new_pos):
signal_data["position_updated"] = true
signal_data["updated_position"] = new_pos
character.position_updated.connect(callback)
# 执行平滑移动
character.set_position_smooth(target_pos)
# 等待移动完成
for j in range(100):
await get_tree().physics_frame
if not character.is_moving_smooth:
break
# 验证位置是否更新
if signal_data["position_updated"] and signal_data["updated_position"].distance_to(target_pos) < 1.0:
passed += 1
else:
failed += 1
print(" FAILED iteration ", i + 1)
print(" Position not synced correctly")
character.queue_free()
await get_tree().process_frame
print(" Result: ", passed, "/", TEST_ITERATIONS, " passed")
if failed > 0:
print(" ❌ FAILED: ", failed, " iterations failed")
else:
print(" ✅ PASSED: All iterations successful")
## Feature: godot-ai-town-game, Property 2: 角色移动能力
func test_property_movement_ability():
"""
属性测试:角色移动能力
对于任意创建或加载到场景的角色,该角色应该具有基础移动能力
"""
print("\n[Property Test] Character Movement Ability")
var passed = 0
var failed = 0
for i in range(TEST_ITERATIONS):
# 创建随机角色数据
var char_data = CharacterData.create(
"TestChar" + str(i),
"owner_" + str(i),
Vector2(randf_range(-100, 100), randf_range(-100, 100))
)
var character = CharacterController.new()
add_child(character)
await get_tree().physics_frame
# 初始化角色
character.initialize(char_data)
var initial_pos = character.global_position
# 测试移动能力
var move_direction = Vector2(randf_range(-1, 1), randf_range(-1, 1)).normalized()
character.move_to(move_direction)
# 等待几帧
for j in range(5):
await get_tree().physics_frame
character.move_to(Vector2.ZERO)
await get_tree().physics_frame
var final_pos = character.global_position
var moved = initial_pos.distance_to(final_pos) > 0.1
if moved:
passed += 1
else:
failed += 1
print(" FAILED iteration ", i + 1)
print(" Character did not move")
character.queue_free()
await get_tree().process_frame
print(" Result: ", passed, "/", TEST_ITERATIONS, " passed")
if failed > 0:
print(" ❌ FAILED: ", failed, " iterations failed")
else:
print(" ✅ PASSED: All iterations successful")