创建新工程
This commit is contained in:
206
tests/test_character_controller.gd
Normal file
206
tests/test_character_controller.gd
Normal file
@@ -0,0 +1,206 @@
|
||||
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")
|
||||
Reference in New Issue
Block a user