godot-plateformer/_props/dark_material_ball/dark_material_ball.gd

112 lines
2.8 KiB
GDScript3
Raw Normal View History

2026-01-15 13:01:31 +08:00
extends CharacterBody2D
@onready var player_collectable_volumn: PlayerTriggerVolumn = %PlayerCollectableVolumn
@onready var hook_attract_volumn: Area2D = %HookAttractVolumn
2026-02-07 15:53:02 +08:00
@export var respawn_time: float = 2.0
2026-01-15 13:01:31 +08:00
enum State {
IDLE,
PULLED_BY_HOOK,
COLLECTED
}
var _current_state: State = State.IDLE
2026-02-07 15:53:02 +08:00
var _spawn_position: Vector2
2026-01-15 13:01:31 +08:00
## 拉回速度
@export var pull_speed: float = 800.0
## 拉回目标(玩家)
var _pull_target: Node2D
func _ready() -> void:
2026-02-07 15:53:02 +08:00
_spawn_position = global_position
2026-01-15 13:01:31 +08:00
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:
2026-02-07 15:53:02 +08:00
_on_collected_enter()
2026-01-15 13:01:31 +08:00
## 钩爪击中时调用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)
2026-02-07 15:53:02 +08:00
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)