2026-01-15 13:01:31 +08:00
|
|
|
|
extends CharacterBody2D
|
|
|
|
|
|
|
|
|
|
|
|
@onready var player_collectable_volumn: PlayerTriggerVolumn = %PlayerCollectableVolumn
|
|
|
|
|
|
@onready var hook_attract_volumn: Area2D = %HookAttractVolumn
|
|
|
|
|
|
|
|
|
|
|
|
enum State {
|
|
|
|
|
|
IDLE,
|
|
|
|
|
|
PULLED_BY_HOOK,
|
|
|
|
|
|
COLLECTED
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var _current_state: State = State.IDLE
|
|
|
|
|
|
|
|
|
|
|
|
## 拉回速度
|
|
|
|
|
|
@export var pull_speed: float = 800.0
|
|
|
|
|
|
## 拉回目标(玩家)
|
|
|
|
|
|
var _pull_target: Node2D
|
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
|
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:
|
|
|
|
|
|
queue_free()
|
|
|
|
|
|
|
|
|
|
|
|
## 钩爪击中时调用(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()
|
|
|
|
|
|
|
2026-01-15 16:09:20 +08:00
|
|
|
|
func get_attraction_force(pos: Vector2) -> Vector2:
|
|
|
|
|
|
# 返回 (direction, strength) 格式
|
|
|
|
|
|
var dir := (global_position - pos).normalized()
|
|
|
|
|
|
var strength := 1500 # 调整这个值控制吸引力转向速度
|
|
|
|
|
|
return dir * strength
|
|
|
|
|
|
|
2026-01-15 13:01:31 +08:00
|
|
|
|
##如果玩家进入收集区域,则切换为已收集状态。
|
|
|
|
|
|
func _on_player_collected(body:CharacterBody2D) -> void:
|
|
|
|
|
|
if body is Player:
|
|
|
|
|
|
body.hsm.dispatch(&"trigger_external_dash")
|
|
|
|
|
|
change_state(State.COLLECTED)
|