godot-plateformer/_props/dark_material_ball/dark_material_ball.gd

112 lines
2.8 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)