X-Git-Url: http://git.purplebirdman.com/frog-ninja.git/blobdiff_plain/45b19375d7b7586954c198f370a2ea9fc4fb7655..2e697142bf5e1b94429281572bdc1cbf5868d5ce:/player/player.gd diff --git a/player/player.gd b/player/player.gd index 11e41ac..c6f39a8 100644 --- a/player/player.gd +++ b/player/player.gd @@ -1,180 +1,33 @@ extends CharacterBody3D class_name Player -########## -# settings -########## @export_group("Movement") -@export var walk_speed := 8.0 +@export var walk_speed := 10.0 @export var dash_length := 10.0 - -@export var air_speed := 3.0 -@export var acceleration := 30.0 +@export var acceleration := 20.0 @export var rotation_speed := 10.0 @export var idle_timeout := 5.0 -@export_group("Camera") -@export_range(1.0, 10.0) var camera_distance := 2.0 -@export_range(0.0, 1.0) var mouse_sensitivity := 0.15 -@export_range(0.0, 1.0) var mouse_sensitivity_x := 1.0 -@export_range(0.0, 1.0) var mouse_sensitivity_y := 0.5 -@export_range(0.0, 10.0) var joystick_sensitivity_x := 4.0 -@export_range(0.0, 10.0) var joystick_sensitivity_y := 2.0 - -###### -# init -###### - -@onready var _camera_pivot: Node3D = %camera_pivot -@onready var _camera: Camera3D = %camera -@onready var _camera_spring: SpringArm3D = %spring -@onready var _skin: AnimatedSkin = %skin -var _last_movement_direction := rotation -var _floor_normal := Vector3.ONE -var _ground_slope_input := 0.0 -var _camera_input_direction := Vector2.ZERO -var _idle_time: float = 0.0 -var _player_speed: float = walk_speed +var idle_time := 0.00 +var last_movement_direction := rotation +var floor_normal := Vector3.ZERO +var ground_slope_input := 0.0 +var state := "" -enum CameraInput {MOUSE, JOYSTICK} -var _camera_input_method := CameraInput.MOUSE +@onready var input: InputHandler = $Input +@onready var model: PlayerModel = $Model +@onready var skin: SkeletonSkin3D = $Visual +@onready var camera_handler: CameraHandler = $CameraHandler func _ready() -> void: - _camera_spring.spring_length = camera_distance - - - -####### -# input -####### - -func _unhandled_input(event: InputEvent) -> void: - # If user clicks on the window, capture the mouse and direct the camera with it - if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED: - return - - #_camera_input_direction *= mouse_sensitivity - if event is InputEventMouseMotion: - _camera_input_method = CameraInput.MOUSE - _camera_input_direction = event.screen_relative * mouse_sensitivity - elif event is InputEventJoypadMotion: - # TODO: add these settings! - _camera_input_method = CameraInput.JOYSTICK - _camera_input_direction = Input.get_vector("camera-left", "camera-right", "camera-up", "camera-down") - _camera_input_direction *= Vector2(joystick_sensitivity_x, -joystick_sensitivity_y) + input.camera = %camera + camera_handler.input = input + skin.assign_skeleton(model.skeleton) -func _input(event: InputEvent): - if event.is_action_pressed("player-dash"): - _skin.transition_dash() - _player_dash() - elif event.is_action_pressed("player-slash"): - _skin.sword_visible() - _skin.transition_slash() - elif event.is_action_pressed("player-shoot"): - _skin.gun_visible() - _skin.transition_gunfire() - - -########## -# movement -########## - func _physics_process(delta: float) -> void: - _process_camera(delta) - _process_player(delta) - - -# Get the XZ input direction based on player's input relative to the camera -func _get_player_move_direction() -> Vector3: - var input_dir := Input.get_vector("player-left", "player-right", "player-forward", "player-backward") - var forward := _camera.global_basis.z - var right := _camera.global_basis.x - var move_direction := (forward * input_dir.y + right * input_dir.x).normalized() - move_direction.y = 0 - return move_direction - - -func _process_camera(delta: float) -> void: - # vertical camera rotation - _camera_pivot.rotation.x += _camera_input_direction.y * mouse_sensitivity_y * delta - _camera_pivot.rotation.x = clamp(_camera_pivot.rotation.x, -PI / 6, PI / 3) - - # horizontal camera rotation - _camera_pivot.rotation.y -= _camera_input_direction.x * mouse_sensitivity_x * delta - - # reset mouse movement vector if mouse input - if _camera_input_method == CameraInput.MOUSE: - _camera_input_direction = Vector2.ZERO - - # change spring length depending on player speed - _camera_spring.spring_length = lerp( - _camera_spring.spring_length, camera_distance + velocity.length() / 4, delta - ) - - -func _process_player_on_floor(delta: float): - var move_direction := _get_player_move_direction() - - # if we're not stuck, then it's okay to set the velocity - _floor_normal = get_floor_normal() - _ground_slope_input = (PI / 2) - velocity.angle_to(_floor_normal) - velocity = velocity.move_toward( - move_direction * (_player_speed + _ground_slope_input * _player_speed), - acceleration * delta - ) - var movement_speed := Vector3(velocity.x, 0, velocity.z).length() - - # also, if we're moving, we're not idle - if move_direction.length() < 0.2: - if velocity == Vector3.ZERO: - _idle_time += delta - else: - _last_movement_direction = move_direction - _idle_time = 0.0 - - # if camera is unlocked, rotate whole skin to face movement direction - var skin_target_angle := Vector3.BACK.signed_angle_to(_last_movement_direction, Vector3.UP) - _skin.global_rotation.y = lerp_angle( - _skin.global_rotation.y, - skin_target_angle, - rotation_speed * delta - ) - - # lean into player momentum just a little bit - _skin.rotation.z = lerp_angle( - _skin.rotation.z, - clamp(_last_movement_direction.signed_angle_to(velocity, Vector3.UP) * movement_speed * 0.08, -PI/4, PI/ 4), - rotation_speed * delta * 0.25 - ) - - # let skin know how fast player is moving along the ground - _skin.set_walking_speed(movement_speed) - - -func _process_player(delta: float) -> void: - if is_on_floor(): - _process_player_on_floor(delta) - - if _idle_time > idle_timeout: - _skin.transition_move() - else: - _skin.transition_move() - else: - _skin.transition_falling() - velocity += get_gravity() * air_speed * delta - - move_and_slide() - -######### -# actions -######### - -func _player_dash(): - if _last_movement_direction != Vector3.ZERO: - var dash_local_pos = _last_movement_direction * dash_length - # TODO: check if valid position, crop the vector to last valid position - global_position += dash_local_pos + var input_pkt := input.get_player_input() + model.update(input_pkt, delta)