extends CharacterBody2D @onready var player_collectable_volumn: PlayerTriggerVolumn = %PlayerCollectableVolumn @onready var hook_attract_volumn: Area2D = %HookAttractVolumn @export var respawn_time: float = 2.0 enum State { IDLE, PULLED_BY_HOOK, COLLECTED } var _current_state: State = State.IDLE var _spawn_position: Vector2 ## 拉回速度 @export var pull_speed: float = 800.0 ## 拉回目标(玩家) var _pull_target: Node2D func _ready() -> void: _spawn_position = global_position player_collectable_volumn.player_entered.connect(_on_player_collected) ##状态管理函数 func change_state(in_state: State) -> void: if in_state == _current_state: return ## 退出State的逻辑 match _current_state: State.IDLE: pass State.PULLED_BY_HOOK: pass State.COLLECTED: pass _current_state = in_state ## 进入State的逻辑 match in_state: State.IDLE: pass State.PULLED_BY_HOOK: pass State.COLLECTED: _on_collected_enter() ## 钩爪击中时调用(hit_pos 是击中点,hook 是钩爪实例) func on_hook_hit(hit_pos: Vector2, hook: Hook) -> void: # 通过钩爪组件获取发射者(玩家) _pull_target = hook._binded_hook_comp.owner as Node2D if _pull_target: change_state(State.PULLED_BY_HOOK) func _physics_process(delta: float) -> void: if _current_state == State.PULLED_BY_HOOK and _pull_target: var direction := (_pull_target.global_position - global_position).normalized() velocity = direction * pull_speed move_and_slide() func get_attraction_force(pos: Vector2) -> Vector2: # 返回 (direction, strength) 格式 var dir := (global_position - pos).normalized() var strength := 1500 # 调整这个值控制吸引力转向速度 return dir * strength ##如果玩家进入收集区域,则切换为已收集状态。 func _on_player_collected(body:CharacterBody2D) -> void: if body is Player: body.hsm.dispatch(&"trigger_external_dash") change_state(State.COLLECTED) func _on_collected_enter() -> void: velocity = Vector2.ZERO # 隐藏 visible = false set_physics_process(false) # 关闭碰撞 if has_node("CollisionShape2D"): $CollisionShape2D.disabled = true player_collectable_volumn.monitoring = false player_collectable_volumn.monitorable = false hook_attract_volumn.monitoring = false hook_attract_volumn.monitorable = false # 启动重生流程 _respawn_after_delay() func _respawn_after_delay() -> void: await get_tree().create_timer(respawn_time).timeout global_position = _spawn_position visible = true set_physics_process(true) if has_node("CollisionShape2D"): $CollisionShape2D.disabled = false player_collectable_volumn.monitoring = true player_collectable_volumn.monitorable = true hook_attract_volumn.monitoring = true hook_attract_volumn.monitorable = true change_state(State.IDLE)