@tool class_name ProAnimatedSprite2D extends AnimatedSprite2D @export var autostart := true # 从 intro 到 next 的配置信息 # { # "animation_intro": "", # "intro_loop": 1, # "animation_wait_time": 0.0, # "animation_next": "" # } @export var action_configs: Array[Dictionary] = [] # { # "animation": "", # "velocity": Vector2(0, 0) # } @export var move_configs: Array[Dictionary] = [] # 从 intro 到 next 的配置信息 var auto_checkout_dict = { # intro -> {state_config instance} } # 播放 animation 的同时,进行移动 var animation_velocity = { # animation -> velocity } func _ready() -> void: if Engine.is_editor_hint(): return _load_config() if autostart and animation: # 制造一点错差 frame = randi() % sprite_frames.get_frame_count(animation) play() animation_finished.connect(_on_animation_finished) animation_changed.connect(_on_animation_start) animation_looped.connect(_on_animation_start) func _load_config(): # load auto_checkout_dict for i in range(action_configs.size()): var state_config = action_configs[i] if sprite_frames and sprite_frames.has_animation(state_config.animation_intro): # intro 的 animation 关闭循环 sprite_frames.set_animation_loop(state_config.animation_intro, false) auto_checkout_dict[state_config.animation_intro] = action_configs[i] # load animation_frame_offsets for i in range(move_configs.size()): var move_config = move_configs[i] if sprite_frames and sprite_frames.has_animation(move_config.animation): animation_velocity[move_config.animation] = move_config.velocity func _reset_loop(intro: String): for c in action_configs: if c.animation_intro == intro: auto_checkout_dict[intro].intro_loop = max(1, c.intro_loop) func _on_animation_finished() -> void: var intro = animation if auto_checkout_dict.has(intro): auto_checkout_dict[intro].intro_loop -= 1 if auto_checkout_dict[intro].intro_loop <= 0: # reset loop _reset_loop(intro) var wait_time = auto_checkout_dict[intro].animation_wait_time var next = auto_checkout_dict[intro].animation_next if wait_time > 0: pause() get_tree().create_timer(wait_time).timeout.connect(play.bind(next)) else: play(next) var velocity := Vector2.ZERO func _on_animation_start(): if not animation or not animation_velocity.has(animation): velocity = Vector2.ZERO return velocity = animation_velocity[animation] * speed_scale if GlobalConfig.DEBUG: print("animation ", animation, " velocity=", velocity) func _physics_process(delta: float) -> void: if Engine.is_editor_hint() or not animation or not velocity: return position += velocity * delta # temporary set velocity func set_animation_velocity(anim: String, v: Vector2) -> void: animation_velocity[anim] = v if GlobalConfig.DEBUG: print("set_animation_velocity:", anim, v)