godot-plateformer/_player/avatar.gd

144 lines
3.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.

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
@onready var ground_companion: Area2D = %GroundCompanion
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()))
var x: float = clampf(abs(velocity.x),1,1000) * .2 * sign(velocity.x)
var y: float = clampf(abs(velocity.y),1,1000) * .2 * sign(velocity.y)
draw_line(Vector2.ZERO,Vector2(x, 0),Color.RED,4)
draw_line(Vector2.ZERO,Vector2(0, y),Color.GREEN,4)
func _process(delta: float) -> void:
queue_redraw()
func set_move_input(dir: Vector2) -> void:
m_input_intent_direction = dir
func get_move_input() -> Vector2:
return m_input_intent_direction
## 更宽泛的floor检测
func get_is_on_floor() -> bool:
return self.is_on_floor() or ground_companion.has_overlapping_areas() or ground_companion.has_overlapping_bodies()
#region 输入处理
'''对于单次的输入触发动作,我们发送一个格式为
want_to_...的事件给hsm用来尝试触发
'''
func press_jump() -> void:
m_jump_press = true
hsm.dispatch(&"trigger_jump")
func release_jump() -> void:
m_jump_press = false
hsm.dispatch(&"completed_jump")
func press_dash() -> void:
m_dash_press = true
hsm.dispatch(&"trigger_dash")
func release_dash() -> void:
m_dash_press = false
hsm.dispatch(&"completed_dash")
func press_climb() -> void:
m_climb_press = true
hsm.dispatch(&"trigger_climb")
func release_climb() -> void:
m_climb_press = false
hsm.dispatch(&"completed_climb")
func press_grap_hook() -> void:
m_grap_hook_press = true
hsm.dispatch(&"trigger_grap_hook")
func release_grap_hook() -> void:
m_grap_hook_press = true
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)