初次提交
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
## PlayerManager — 玩家管理 Autoload
|
||||
## S0:WASD 移动 + 位置查询
|
||||
## S1:自动施法
|
||||
## S4:停步蓄力 / 冲刺边沿检测(P6-N69、P6-N36)
|
||||
extends Node
|
||||
|
||||
const MOVE_SPEED: float = 200.0
|
||||
const MOVE_THRESHOLD_NORM: float = 0.1
|
||||
const CHARGE_TRIGGER_TIME: float = 1.5
|
||||
|
||||
var _position: Vector2 = Vector2.ZERO
|
||||
var _velocity: Vector2 = Vector2.ZERO
|
||||
var _player_node: Node2D = null
|
||||
|
||||
var _equipped_core: CoreDefinition = null
|
||||
var _equipped_compiled: CompiledDeck = null
|
||||
var _cast_timer: float = 0.0
|
||||
var _cast_interval: float = 0.5
|
||||
|
||||
var _is_moving: bool = false
|
||||
var _stationary_time: float = 0.0
|
||||
var _charge_triggered: bool = false
|
||||
var _last_dash_time: float = -999.0
|
||||
|
||||
var kill_count: int = 0
|
||||
|
||||
func _ready() -> void:
|
||||
EventBus.subscribe(EventID.ENEMY_KILLED, _on_enemy_killed)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
_handle_movement(delta)
|
||||
_handle_charge_state(delta)
|
||||
_handle_auto_cast(delta)
|
||||
|
||||
func _handle_movement(delta: float) -> void:
|
||||
var dir := Vector2(
|
||||
Input.get_axis("ui_left", "ui_right"),
|
||||
Input.get_axis("ui_up", "ui_down")
|
||||
)
|
||||
_is_moving = dir.length() > MOVE_THRESHOLD_NORM
|
||||
if _is_moving:
|
||||
dir = dir.normalized()
|
||||
_velocity = dir * MOVE_SPEED
|
||||
else:
|
||||
_velocity = Vector2.ZERO
|
||||
_position += _velocity * delta
|
||||
if _player_node:
|
||||
_player_node.global_position = _position
|
||||
|
||||
func _handle_charge_state(delta: float) -> void:
|
||||
if Input.is_action_just_pressed("ui_accept"):
|
||||
_last_dash_time = Time.get_ticks_msec() / 1000.0
|
||||
EventBus.emit(EventID.DASH_TRIGGERED, {
|
||||
"caster_id": 0,
|
||||
"stationary_time": _stationary_time,
|
||||
})
|
||||
_stationary_time = 0.0
|
||||
_charge_triggered = false
|
||||
return
|
||||
|
||||
if _is_moving:
|
||||
if _stationary_time > 0.0:
|
||||
_stationary_time = 0.0
|
||||
_charge_triggered = false
|
||||
EventBus.emit(EventID.CHARGE_STATE_CHANGED, {"caster_id": 0, "progress": 0.0})
|
||||
else:
|
||||
_stationary_time += delta
|
||||
if _stationary_time >= 0.3:
|
||||
var prog: float = clampf(_stationary_time / CHARGE_TRIGGER_TIME, 0.0, 1.0)
|
||||
EventBus.emit(EventID.CHARGE_STATE_CHANGED, {"caster_id": 0, "progress": prog})
|
||||
if _stationary_time >= CHARGE_TRIGGER_TIME and not _charge_triggered:
|
||||
_charge_triggered = true
|
||||
EventBus.emit(EventID.CHARGE_FIRED, {"caster_id": 0})
|
||||
|
||||
func _handle_auto_cast(delta: float) -> void:
|
||||
if _equipped_compiled == null or _equipped_compiled.is_empty():
|
||||
return
|
||||
_cast_timer -= delta
|
||||
if _cast_timer <= 0.0:
|
||||
_cast_timer = _cast_interval
|
||||
SpellEvaluator.execute_compiled(_equipped_compiled, 0, _position)
|
||||
|
||||
func equip_wand(core: CoreDefinition, compiled: CompiledDeck) -> void:
|
||||
_equipped_core = core
|
||||
_equipped_compiled = compiled
|
||||
_cast_interval = core.cast_interval if core else 0.5
|
||||
_cast_timer = 0.0
|
||||
|
||||
func get_position() -> Vector2:
|
||||
return _position
|
||||
|
||||
func get_velocity() -> Vector2:
|
||||
return _velocity
|
||||
|
||||
func get_stationary_time() -> float:
|
||||
return _stationary_time
|
||||
|
||||
func is_charge_triggered() -> bool:
|
||||
return _charge_triggered
|
||||
|
||||
func set_player_node(node: Node2D) -> void:
|
||||
_player_node = node
|
||||
if node:
|
||||
_position = node.global_position
|
||||
|
||||
func _on_enemy_killed(_payload: Dictionary) -> void:
|
||||
kill_count += 1
|
||||
|
||||
func reset() -> void:
|
||||
_position = Vector2.ZERO
|
||||
_velocity = Vector2.ZERO
|
||||
_player_node = null
|
||||
_equipped_compiled = null
|
||||
_equipped_core = null
|
||||
_cast_timer = 0.0
|
||||
_is_moving = false
|
||||
_stationary_time = 0.0
|
||||
_charge_triggered = false
|
||||
kill_count = 0
|
||||
Reference in New Issue
Block a user