134 lines
3.3 KiB
GDScript
134 lines
3.3 KiB
GDScript
class_name Player
|
|
extends CharacterBody2D
|
|
|
|
|
|
@export_group("Grounded Movement")
|
|
@export var walk_speed: float = 120.0
|
|
@export var acceleration: float = 120.0
|
|
@export var stopping_force: float = 320.0
|
|
@export var stop_threshold: float = 4.0
|
|
@export var turning_force: float = 450.0
|
|
|
|
|
|
@onready var state_chart: StateChart = %StateChart
|
|
@onready var graphics: Node2D = %Graphics
|
|
@onready var animation_player: AnimationPlayer = %AnimationPlayer
|
|
|
|
@onready var front_arm_pivot: Node2D = %FrontArmPivot
|
|
@onready var back_arm_pivot: Node2D = %BackArmPivot
|
|
|
|
|
|
var input_dir: float = 0.0
|
|
var aim_back_arm: bool = false
|
|
|
|
var _was_on_floor: bool = true
|
|
var _highlighted_pickup: Pickup = null
|
|
|
|
|
|
func _ready() -> void:
|
|
state_chart.set_expression_property(&"player", self)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
_face_body_to_mouse()
|
|
|
|
if is_on_floor():
|
|
state_chart.send_event(&"landed")
|
|
else:
|
|
state_chart.send_event(&"left_ground")
|
|
|
|
var old_input_dir = input_dir
|
|
input_dir = signf(Input.get_axis(&"move_left", &"move_right"))
|
|
if input_dir != old_input_dir:
|
|
state_chart.send_event(&"input_dir_changed")
|
|
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if event.is_action_pressed(&"aim"):
|
|
state_chart.send_event(&"aim_pressed")
|
|
elif event.is_action_released(&"aim"):
|
|
state_chart.send_event(&"aim_released")
|
|
|
|
|
|
func toss_held_object() -> void:
|
|
pass
|
|
|
|
|
|
func _face_body_to_mouse() -> void:
|
|
if get_local_mouse_position().x < 0.0:
|
|
graphics.scale.x = -1.0
|
|
else:
|
|
graphics.scale.x = 1.0
|
|
|
|
|
|
func _face_arm_to_mouse(pivot: Node2D) -> void:
|
|
var mouse_pos = graphics.get_local_mouse_position()
|
|
|
|
var pivot_xform = pivot.get_relative_transform_to_parent(graphics)
|
|
pivot.rotation = pivot_xform.origin.angle_to_point(mouse_pos)
|
|
|
|
|
|
#region Movement States
|
|
func _active_physics_process(delta: float) -> void:
|
|
move_and_slide()
|
|
|
|
|
|
#region Grounded States
|
|
func _grounded_child_state_entered() -> void:
|
|
state_chart.send_event(&"input_dir_changed")
|
|
|
|
|
|
func _standing_entered() -> void:
|
|
velocity.x = 0.0
|
|
|
|
|
|
func _walking_process(delta: float) -> void:
|
|
velocity.x += acceleration * input_dir * delta
|
|
velocity.x = clampf(velocity.x, -walk_speed, walk_speed)
|
|
animation_player.speed_scale = inverse_lerp(0, walk_speed, velocity.x) * graphics.scale.x
|
|
|
|
|
|
func _stopping_physics_process(delta: float) -> void:
|
|
velocity.x -= stopping_force * signf(velocity.x) * delta
|
|
if absf(velocity.x) <= stop_threshold:
|
|
velocity.x = 0.0
|
|
state_chart.send_event(&"stopped")
|
|
|
|
|
|
func _turning_physics_process(delta: float) -> void:
|
|
velocity.x += turning_force * input_dir * delta
|
|
if signf(velocity.x) != -input_dir:
|
|
state_chart.send_event(&"turn_finished")
|
|
|
|
|
|
func _aiming_physics_process(delta: float) -> void:
|
|
_face_arm_to_mouse(front_arm_pivot)
|
|
if aim_back_arm:
|
|
_face_arm_to_mouse(back_arm_pivot)
|
|
|
|
|
|
func _aiming_exited() -> void:
|
|
front_arm_pivot.rotation = PI * 0.5
|
|
back_arm_pivot.rotation = PI * 0.5
|
|
#endregion
|
|
|
|
|
|
#region Airborn States
|
|
func _airborn_physics_process(delta: float) -> void:
|
|
velocity += get_gravity() * delta
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
#region Collision Signals
|
|
func _on_pickup_area_entered(area: Area2D) -> void:
|
|
if not _highlighted_pickup:
|
|
_highlighted_pickup = area.get_parent() as Pickup
|
|
_highlighted_pickup.highlight = true
|
|
|
|
|
|
func _on_pickup_area_exited(area: Area2D) -> void:
|
|
if _highlighted_pickup == (area.get_parent() as Pickup):
|
|
_highlighted_pickup.highlight = false
|
|
_highlighted_pickup = null
|
|
#endregion
|