126 lines
3.0 KiB
GDScript
126 lines
3.0 KiB
GDScript
class_name Player extends Node3D
|
|
|
|
#region variables
|
|
@export_group("References")
|
|
@export var _keyboard: GameKeyboard
|
|
@export var _sfx_player: AudioStreamPlayer3D
|
|
|
|
@export_group("Animation")
|
|
|
|
@export_subgroup("Moving")
|
|
@export var _move_duration: float = 0.1
|
|
@export var _move_hop_height: float = 1
|
|
|
|
@export_group("SFX")
|
|
@export var _hop_sfx: AudioStream
|
|
@export var _hop_sfx_volume: float = 0.4
|
|
|
|
var _current_key: GameKey
|
|
var _starting_keycode: Key = KEY_H
|
|
var _rotation: Quaternion
|
|
|
|
var _move_timer: float
|
|
var _is_moving: bool
|
|
var _prev_pos: Vector3
|
|
|
|
var _polyphonic: AudioStreamPlaybackPolyphonic
|
|
|
|
#endregion
|
|
|
|
|
|
#region builtins
|
|
func _ready() -> void:
|
|
_keyboard.key_pressed.connect(_on_keyboard_key_pressed)
|
|
_current_key = _keyboard.query_key_by_keycode(_starting_keycode)
|
|
if _current_key:
|
|
global_transform = _current_key.player_pos_marker.global_transform
|
|
_keyboard.emit_player_current_key_changed(_current_key)
|
|
|
|
_sfx_player.play()
|
|
_polyphonic = _sfx_player.get_stream_playback()
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
_animate(delta)
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region movement
|
|
func _move(game_key: GameKey) -> void:
|
|
var look_from := _current_key.player_pos_marker.transform * _current_key.transform
|
|
var look_target := game_key.player_pos_marker.transform * game_key.transform
|
|
look_target.origin.y = look_from.origin.y
|
|
var looking := look_from.looking_at(look_target.origin, Vector3.UP, true)
|
|
_rotation = looking.basis.get_rotation_quaternion()
|
|
|
|
_prev_pos = _current_key.player_pos_marker.global_position
|
|
_move_timer = _move_duration
|
|
if _is_moving:
|
|
_finish_move(true)
|
|
_is_moving = true
|
|
|
|
_current_key = game_key
|
|
_keyboard.emit_player_current_key_changed(game_key)
|
|
_play_sfx(_hop_sfx, _hop_sfx_volume)
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region animation
|
|
func _animate(delta: float) -> void:
|
|
if not _current_key:
|
|
return
|
|
|
|
if _move_timer <= 0:
|
|
if _is_moving:
|
|
_is_moving = false
|
|
_finish_move(false)
|
|
global_position = _animate_position()
|
|
else:
|
|
_move_timer -= delta
|
|
var lerp_value := 1 - (_move_timer / _move_duration)
|
|
global_position = lerp(_prev_pos, _animate_position(), lerp_value)
|
|
var hop_value := 1 - absf(lerp_value * 2 - 1)
|
|
hop_value = 1 - pow(1 - hop_value, 3)
|
|
global_position.y += hop_value * _move_hop_height
|
|
|
|
global_rotation = _animate_rotation()
|
|
|
|
|
|
func _animate_position() -> Vector3:
|
|
return _current_key.player_pos_marker.global_position
|
|
|
|
|
|
func _animate_rotation() -> Vector3:
|
|
var rot_translate := (
|
|
_current_key.get_default_transform().inverse()
|
|
* _current_key.player_pos_marker.global_transform
|
|
)
|
|
return (_rotation * rot_translate.basis.get_rotation_quaternion()).get_euler()
|
|
|
|
|
|
func _finish_move(_interrupted: bool) -> void:
|
|
_keyboard.emit_player_finished_move(_current_key)
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region sounds
|
|
func _play_sfx(stream: AudioStream, volume_linear: float = 1) -> void:
|
|
_polyphonic.play_stream(stream, 0, linear_to_db(volume_linear))
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region event handlers
|
|
func _on_keyboard_key_pressed(game_key: GameKey) -> void:
|
|
if _current_key and _current_key.is_adjacent(game_key):
|
|
_move(game_key)
|
|
|
|
#endregion
|