229 lines
6.4 KiB
GDScript
229 lines
6.4 KiB
GDScript
extends CharacterBody2D
|
|
|
|
class_name MainPlayer
|
|
|
|
enum MOVEMENT_STATUS {
|
|
IDLE,
|
|
WALKING,
|
|
RUNNING,
|
|
LAYING_STAY,
|
|
LAYING_MOVING,
|
|
CLIMBING_STAY,
|
|
CLIMBING,
|
|
}
|
|
|
|
@export var player_movement_rect := Rect2(50, -500, 1400, 1000)
|
|
@export var velocity_ratio := 1.0
|
|
@export var action_locked := false:
|
|
set(val):
|
|
action_locked = val
|
|
_process_action_lock()
|
|
@export var current_status: MOVEMENT_STATUS
|
|
@export var facing_direction := Vector2(1.0, -1.0)
|
|
@export var is_laying := false:
|
|
set(val):
|
|
is_laying = val
|
|
# reset the facing direction wether the player is laying or not.
|
|
_reset_face_direction()
|
|
if is_laying:
|
|
is_climbing = false
|
|
@export var is_climbing := false:
|
|
set(val):
|
|
is_climbing = val
|
|
# reset the facing direction wether the player is climbing or not.
|
|
_reset_face_direction()
|
|
if is_climbing:
|
|
is_laying = false
|
|
@export var running_locked := false
|
|
@export var speed_walking := 90.0
|
|
@export var speed_runnig := 160.0
|
|
@export var speed_laying := 60.0
|
|
@export var speed_climbing := 60.0
|
|
#const JUMP_VELOCITY = -400.0
|
|
@export var footstep_base_speed := 60.0
|
|
|
|
@onready var footstep_timer = %FootstepTimer as Timer
|
|
@onready var sprite = %AnimatedSprite2D as AnimatedSprite2D
|
|
|
|
|
|
func _ready() -> void:
|
|
# _reset_face_direction()
|
|
footstep_timer.timeout.connect(_on_footstep_timer_timeout)
|
|
footstep_timer.stop()
|
|
|
|
|
|
func _on_footstep_timer_timeout():
|
|
# ground node is sibling of the player node.
|
|
var ground_loader = SceneManager.get_ground_loader()
|
|
if ground_loader:
|
|
ground_loader.play_footstep_sound()
|
|
|
|
|
|
func _reset_face_direction() -> void:
|
|
facing_direction = Vector2(1, -1)
|
|
|
|
|
|
func _process_action_lock() -> void:
|
|
# reset status to idle or stay
|
|
if action_locked:
|
|
velocity = Vector2.ZERO
|
|
if current_status == MOVEMENT_STATUS.WALKING or current_status == MOVEMENT_STATUS.RUNNING:
|
|
current_status = MOVEMENT_STATUS.IDLE
|
|
elif current_status == MOVEMENT_STATUS.LAYING_MOVING:
|
|
current_status = MOVEMENT_STATUS.LAYING_STAY
|
|
elif current_status == MOVEMENT_STATUS.CLIMBING:
|
|
current_status = MOVEMENT_STATUS.CLIMBING_STAY
|
|
_play_animation()
|
|
|
|
|
|
# return whether the player status or facing direction has changed.
|
|
func _check_status(direction) -> bool:
|
|
var tmp_status = current_status
|
|
var new_facing_direction := facing_direction
|
|
if is_laying:
|
|
if direction.x:
|
|
new_facing_direction.x = direction.x
|
|
tmp_status = MOVEMENT_STATUS.LAYING_MOVING
|
|
else:
|
|
tmp_status = MOVEMENT_STATUS.LAYING_STAY
|
|
elif is_climbing:
|
|
if direction.y:
|
|
new_facing_direction.y = direction.y
|
|
tmp_status = MOVEMENT_STATUS.CLIMBING
|
|
else:
|
|
tmp_status = MOVEMENT_STATUS.CLIMBING_STAY
|
|
else:
|
|
if direction.x:
|
|
new_facing_direction.x = direction.x
|
|
tmp_status = MOVEMENT_STATUS.WALKING
|
|
if !running_locked and Input.is_action_pressed("run"):
|
|
tmp_status = MOVEMENT_STATUS.RUNNING
|
|
else:
|
|
tmp_status = MOVEMENT_STATUS.IDLE
|
|
if new_facing_direction != facing_direction or tmp_status != current_status:
|
|
facing_direction = new_facing_direction
|
|
current_status = tmp_status
|
|
return true
|
|
return false
|
|
|
|
func set_facing_direction(direction: Vector2) -> void:
|
|
facing_direction = direction
|
|
# update status
|
|
_check_status(direction)
|
|
|
|
func _play_animation() -> void:
|
|
match current_status:
|
|
MOVEMENT_STATUS.IDLE:
|
|
if facing_direction.x > 0.0:
|
|
sprite.play(&"idle_r")
|
|
else:
|
|
sprite.play(&"idle_l")
|
|
footstep_timer.stop()
|
|
MOVEMENT_STATUS.WALKING:
|
|
if facing_direction.x > 0.0:
|
|
sprite.play(&"walking_r")
|
|
else:
|
|
sprite.play(&"walking_l")
|
|
footstep_timer.wait_time = footstep_base_speed / speed_walking
|
|
footstep_timer.start()
|
|
MOVEMENT_STATUS.RUNNING:
|
|
if facing_direction.x > 0.0:
|
|
sprite.play(&"running_r")
|
|
else:
|
|
sprite.play(&"running_l")
|
|
footstep_timer.wait_time = footstep_base_speed / speed_runnig
|
|
footstep_timer.start()
|
|
MOVEMENT_STATUS.LAYING_STAY:
|
|
if facing_direction.x > 0.0:
|
|
sprite.play(&"laying_stay_r")
|
|
else:
|
|
sprite.play(&"laying_stay_l")
|
|
footstep_timer.stop()
|
|
MOVEMENT_STATUS.LAYING_MOVING:
|
|
if facing_direction.x > 0.0:
|
|
sprite.play(&"laying_moving_r")
|
|
else:
|
|
sprite.play(&"laying_moving_l")
|
|
footstep_timer.wait_time = footstep_base_speed / speed_laying
|
|
footstep_timer.start()
|
|
MOVEMENT_STATUS.CLIMBING_STAY:
|
|
sprite.play(&"climbing_stay")
|
|
footstep_timer.stop()
|
|
MOVEMENT_STATUS.CLIMBING:
|
|
if facing_direction.y > 0.0:
|
|
sprite.play(&"climbing_down")
|
|
else:
|
|
sprite.play(&"climbing_up")
|
|
footstep_timer.wait_time = footstep_base_speed / speed_climbing
|
|
footstep_timer.start()
|
|
|
|
|
|
func _get_speed(direction: Vector2) -> Vector2:
|
|
match current_status:
|
|
MOVEMENT_STATUS.WALKING:
|
|
return Vector2(speed_walking * direction.x, 0.0)
|
|
MOVEMENT_STATUS.RUNNING:
|
|
return Vector2(speed_runnig * direction.x, 0.0)
|
|
MOVEMENT_STATUS.LAYING_MOVING:
|
|
return Vector2(speed_laying * direction.x, 0.0)
|
|
MOVEMENT_STATUS.CLIMBING:
|
|
return Vector2(0, speed_climbing * direction.y)
|
|
return Vector2(0, 0)
|
|
|
|
|
|
func _physics_process(_delta: float) -> void:
|
|
if action_locked:
|
|
velocity = Vector2.ZERO
|
|
return
|
|
# Add the gravity.
|
|
#if not is_on_floor():
|
|
#velocity += get_gravity() * delta
|
|
#if Input.is_action_just_pressed("jump") and is_on_floor():
|
|
#velocity.y = JUMP_VELOCITY
|
|
var x_direction := Input.get_axis("left", "right")
|
|
var y_direction := Input.get_axis("up", "down")
|
|
var direction := Vector2(x_direction, y_direction)
|
|
if _check_status(direction):
|
|
_play_animation()
|
|
var speed := _get_speed(direction) as Vector2
|
|
velocity.x = move_toward(velocity.x, speed.x, 300.0) * velocity_ratio
|
|
velocity.y = move_toward(velocity.y, speed.y, 300.0) * velocity_ratio
|
|
move_and_slide()
|
|
position = position.clamp(player_movement_rect.position, player_movement_rect.end)
|
|
_tweak_camera_marker()
|
|
|
|
|
|
# drag the camera marker against the player movement
|
|
# so there will be a better vision in front of the player.
|
|
func _tweak_camera_marker():
|
|
var marker = get_node("./CameraFocusMarker") as Node2D
|
|
if marker:
|
|
marker.tweak_position(velocity, facing_direction)
|
|
|
|
|
|
var note_mutex = Mutex.new()
|
|
var note_pending_time = 0.0
|
|
var note_viewing = false
|
|
|
|
|
|
func check_note(note_time):
|
|
note_mutex.lock()
|
|
note_pending_time += note_time
|
|
if not note_viewing:
|
|
note_viewing = true
|
|
# velocity_ratio = 0.2
|
|
action_locked = true
|
|
get_tree().create_timer(note_time).timeout.connect(_check_slow)
|
|
note_mutex.unlock()
|
|
|
|
|
|
func _check_slow():
|
|
note_mutex.lock()
|
|
note_viewing = false
|
|
action_locked = false
|
|
# velocity_ratio = 1.0
|
|
note_mutex.unlock()
|
|
if note_pending_time:
|
|
note_pending_time = 0.0
|
|
check_note(note_pending_time)
|