Files
whale-town-front-v2/scripts/test_network_npc_animations.gd
xiangwang fc6c3c1bd3 feat: expand multiplayer, chat, and release support
- add network NPC synchronization and dialogue interactions
- add world bulletin publishing and display
- improve authentication, session refresh, and appearance sync
- synchronize player direction and movement animations
- improve input focus and progressive Web loading
- add macOS/Windows builds and deployment configuration
- include required fonts, shaders, and runtime assets
2026-09-08 21:37:43 +08:00

49 lines
2.3 KiB
GDScript

extends SceneTree
const NETWORK_NPC_SCENE: PackedScene = preload("res://scenes/characters/network_npc.tscn")
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
var npc := NETWORK_NPC_SCENE.instantiate()
root.add_child(npc)
npc.call("apply_snapshot", {
"npcId": "npc_niulai",
"name": "牛来",
"scene": "niulai_ambassador",
"version": 1,
"x": 0,
"y": 0,
"movementState": "idle",
})
var animationPlayer := npc.get_node("AnimationPlayer") as AnimationPlayer
assert(npc.collision_layer == 2, "NPC must occupy the dedicated NPC collision layer")
assert(npc.collision_mask == 1, "NPC collision mask must include static map collision")
var npcShape := (npc.get_node("CollisionShape2D") as CollisionShape2D).shape as RectangleShape2D
assert(npcShape.size == Vector2(52, 24), "Niulai must use the adjusted physical footprint")
var nameplate := npc.get_node("Nameplate") as Label
assert(nameplate.get_theme_font_size("font_size") == 16, "NPC names must use the player name font size")
assert(nameplate.get_theme_constant("outline_size") == 3, "NPC names must use the player name outline")
assert(nameplate.get_theme_stylebox("normal") is StyleBoxEmpty, "NPC names must not use the old pill background")
npc.call("_configure_visual", "town_mayor")
assert(is_equal_approx(npc.nameplateOffsetY, -52.0), "The mayor name must follow the visible propeller instead of transparent frame padding")
npc.call("_configure_visual", "niulai_ambassador")
var library := animationPlayer.get_animation_library("")
var expectedRows := {"down": 0, "up": 1, "right": 2, "left": 3}
for direction in expectedRows:
var animationName := "walk_%s" % direction
assert(library.has_animation(animationName), "missing %s" % animationName)
var animation := library.get_animation(animationName)
assert(animation.loop_mode == Animation.LOOP_LINEAR, "%s must loop" % animationName)
assert(animation.track_get_key_count(0) == 4, "%s must contain four frames" % animationName)
for column in range(4):
assert(
animation.track_get_key_value(0, column) == expectedRows[direction] * 4 + column,
"%s uses the wrong spritesheet row" % animationName,
)
npc.call("interact")
assert(root.get_node_or_null("WorldChatBubbleLayer") == null, "NPC interaction must not create a world bubble layer")
print("NETWORK_NPC_ANIMATIONS_OK")
quit()