175 lines
4.3 KiB
GDScript
175 lines
4.3 KiB
GDScript
class_name Player extends CharacterBody2D
|
||
|
||
@onready var locomotion_comp: LocomotionComponent = %LocomotionComponent
|
||
@onready var hsm: LimboHSM = %PlayerHSM
|
||
@onready var wall_detector: WallDetector = %WallDetector
|
||
@onready var hit_box: Area2D = %HitBox
|
||
@onready var spawn_hook_comp: SpawnHookComponet = $SpawnHookComponet
|
||
|
||
@onready var foot_pos_marker: Marker2D = %FootPosMarker
|
||
|
||
enum Direction{LEFT,RIGHT}
|
||
var direction: Direction = Direction.RIGHT: set = _player_direction_changed
|
||
|
||
var m_jump_press: bool = false
|
||
var m_dash_press: bool = false
|
||
var m_climb_press: bool = false
|
||
var m_grap_hook_press: bool = false
|
||
|
||
##用于记录当前玩家输入的朝向
|
||
var m_input_intent_direction: Vector2
|
||
|
||
var is_dead: bool = false:
|
||
set(value):
|
||
is_dead = value
|
||
if is_dead:
|
||
locomotion_comp.is_active = false
|
||
GlobalEvent.boradcast_player_dead_event()
|
||
player_dead.emit()
|
||
|
||
signal player_direction_changed(direction: Direction)
|
||
signal player_dead
|
||
|
||
##落地尘土特效
|
||
signal v_land_dust
|
||
##奔跑尘土特效
|
||
signal v_run_dust
|
||
##跳跃尘土特效
|
||
signal v_jump_dust
|
||
|
||
##跳跃声音特效
|
||
signal s_jump_sound
|
||
|
||
func _ready() -> void:
|
||
self.player_direction_changed.connect(_handle_direction_changed)
|
||
self.hit_box.area_entered.connect(_handle_hit_box_entered)
|
||
self.hit_box.body_entered.connect(_handle_hit_box_entered)
|
||
|
||
func _draw() -> void:
|
||
draw_string(ThemeDB.fallback_font,Vector2.ZERO,str(get_wall_normal()))
|
||
|
||
func _process(delta: float) -> void:
|
||
queue_redraw()
|
||
|
||
func _physics_process(delta: float) -> void:
|
||
|
||
##用於更新輸入的朝向
|
||
m_input_intent_direction = Input.get_vector(
|
||
"move_left",
|
||
"move_right",
|
||
"move_up",
|
||
"move_down"
|
||
)
|
||
|
||
spawn_hook_comp.set_ray_direction(m_input_intent_direction)
|
||
|
||
func _unhandled_input(event: InputEvent) -> void:
|
||
if event.is_echo():
|
||
return
|
||
|
||
#jump input
|
||
if event.is_action_pressed(&"jump"):
|
||
m_jump_press = true
|
||
_handle_jump_press()
|
||
|
||
if event.is_action_released(&"jump"):
|
||
m_jump_press = false
|
||
_handle_jump_release()
|
||
|
||
#dash input
|
||
if event.is_action_pressed(&"dash"):
|
||
m_dash_press = true
|
||
_handle_dash_press()
|
||
|
||
if event.is_action_released(&"dash"):
|
||
m_dash_press = false
|
||
|
||
#climb input
|
||
if event.is_action_pressed(&"climb"):
|
||
m_climb_press = true
|
||
_handle_climb_press()
|
||
|
||
if event.is_action_released(&"climb"):
|
||
m_climb_press = false
|
||
_handle_climb_release()
|
||
|
||
#grap hook input
|
||
if event.is_action_pressed(&"grap_hook"):
|
||
m_grap_hook_press = true
|
||
_handle_grap_hook_press()
|
||
|
||
if event.is_action_released(&"grap_hook"):
|
||
m_grap_hook_press = false
|
||
_handle_grap_hook_release()
|
||
|
||
#region 输入处理
|
||
'''对于单次的输入触发动作,我们发送一个格式为
|
||
want_to_...的事件给hsm,用来尝试触发
|
||
'''
|
||
##处理 jump 单次输入
|
||
func _handle_jump_press() -> void:
|
||
if not m_jump_press:
|
||
return
|
||
|
||
hsm.dispatch(&"trigger_jump")
|
||
|
||
func _handle_jump_release() -> void:
|
||
hsm.dispatch(&"completed_jump")
|
||
|
||
##处理 Dash 单次输入
|
||
func _handle_dash_press() -> void:
|
||
if not m_dash_press:
|
||
return
|
||
hsm.dispatch(&"trigger_dash")
|
||
|
||
##处理 climb 输入
|
||
func _handle_climb_press() -> void:
|
||
if not m_climb_press:
|
||
return
|
||
hsm.dispatch(&"trigger_climb")
|
||
|
||
func _handle_climb_release() -> void:
|
||
hsm.dispatch(&"completed_climb")
|
||
|
||
##处理 Grap Hook 输入
|
||
func _handle_grap_hook_press() -> void:
|
||
hsm.dispatch(&"trigger_grap_hook")
|
||
|
||
func _handle_grap_hook_release() -> void:
|
||
hsm.dispatch(&"completed_grap_hook")
|
||
#endregion
|
||
|
||
##玩家方向改变时更新
|
||
func _handle_direction_changed(value: Direction):
|
||
match value:
|
||
Direction.RIGHT:
|
||
wall_detector.flip_h = false
|
||
Direction.LEFT:
|
||
wall_detector.flip_h = true
|
||
|
||
func _handle_hit_box_entered(node: Node2D)-> void:
|
||
hsm.dispatch(&"try_enter_dead")
|
||
|
||
func _player_direction_changed(value: Direction):
|
||
if self.direction == value:
|
||
return
|
||
direction = value
|
||
player_direction_changed.emit(direction)
|
||
|
||
##播放落地尘土特效
|
||
func on_land_dust() -> void:
|
||
v_land_dust.emit({"world_pos": foot_pos_marker.global_position})
|
||
|
||
##播放落地尘土特效
|
||
func on_run_dust() -> void:
|
||
v_run_dust.emit({"world_pos": foot_pos_marker.global_position})
|
||
|
||
##播放落地尘土特效
|
||
func on_jump() -> void:
|
||
v_jump_dust.emit({"world_pos": foot_pos_marker.global_position})
|
||
s_jump_sound.emit()
|
||
|
||
##工具函数
|
||
static func get_direction_vector(dir: Direction) -> Vector2:
|
||
return Vector2(1,0) if dir == Direction.RIGHT else Vector2(-1,0)
|