From: Clifton Palmer Date: Tue, 6 May 2025 13:56:55 +0000 (+0300) Subject: Refactored and added Fall state X-Git-Url: http://git.purplebirdman.com/frog-ninja.git/commitdiff_plain/3701448ba7e2410adf79dd4a326c0d47a9cc8240 Refactored and added Fall state --- diff --git a/Scene.gd b/Scene.gd deleted file mode 100644 index e733bfb..0000000 --- a/Scene.gd +++ /dev/null @@ -1,28 +0,0 @@ -extends Node3D -class_name Scene - - -@onready var player: Player = %Player -@onready var debug: CanvasLayer = %debug -@onready var version: String = ProjectSettings.get_setting("application/config/version") - - -func _ready() -> void: - debug.draw.add_vector(player, "velocity", 1, 1, Color(0,1,0,1)) - debug.draw.add_vector(player, "floor_normal", 1, 1, Color(0, 0, 1, 1)) - debug.draw.add_vector(player, "last_movement_direction", 1, 1, Color(1,0,0,1)) - - debug.stats.add_property(self, "version", "") - debug.stats.add_property(player, "state", "") - debug.stats.add_property(player, "velocity", "length") - debug.stats.add_property(player, "idle_time", "round") - - -func _input(event: InputEvent) -> void: - if event.is_action_pressed("left_click"): - Input.mouse_mode = Input.MOUSE_MODE_CAPTURED - elif event.is_action_pressed("ui_cancel"): - if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE: - get_tree().quit() - else: - Input.mouse_mode = Input.MOUSE_MODE_VISIBLE diff --git a/Scene.gd.uid b/Scene.gd.uid deleted file mode 100644 index 9d50ef2..0000000 --- a/Scene.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ccournv7m7l4y diff --git a/main.tscn b/main.tscn index 92b1859..d9bdbd8 100644 --- a/main.tscn +++ b/main.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=3 uid="uid://xtdsp4hhl70p"] [ext_resource type="Script" uid="uid://jbyuxajvi3x1" path="res://main.gd" id="1_ig7tw"] -[ext_resource type="PackedScene" uid="uid://cootj2rfyviyb" path="res://test.tscn" id="2_0xm2m"] +[ext_resource type="PackedScene" uid="uid://cootj2rfyviyb" path="res://map/test.tscn" id="2_0xm2m"] [node name="Main" type="Node"] script = ExtResource("1_ig7tw") diff --git a/map/Scene.gd b/map/Scene.gd new file mode 100644 index 0000000..e733bfb --- /dev/null +++ b/map/Scene.gd @@ -0,0 +1,28 @@ +extends Node3D +class_name Scene + + +@onready var player: Player = %Player +@onready var debug: CanvasLayer = %debug +@onready var version: String = ProjectSettings.get_setting("application/config/version") + + +func _ready() -> void: + debug.draw.add_vector(player, "velocity", 1, 1, Color(0,1,0,1)) + debug.draw.add_vector(player, "floor_normal", 1, 1, Color(0, 0, 1, 1)) + debug.draw.add_vector(player, "last_movement_direction", 1, 1, Color(1,0,0,1)) + + debug.stats.add_property(self, "version", "") + debug.stats.add_property(player, "state", "") + debug.stats.add_property(player, "velocity", "length") + debug.stats.add_property(player, "idle_time", "round") + + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("left_click"): + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + elif event.is_action_pressed("ui_cancel"): + if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE: + get_tree().quit() + else: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE diff --git a/map/Scene.gd.uid b/map/Scene.gd.uid new file mode 100644 index 0000000..9d50ef2 --- /dev/null +++ b/map/Scene.gd.uid @@ -0,0 +1 @@ +uid://ccournv7m7l4y diff --git a/map/cube.tscn b/map/cube.tscn new file mode 100644 index 0000000..2984a63 --- /dev/null +++ b/map/cube.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=4 format=3 uid="uid://iwl88y3l713o"] + +[ext_resource type="Material" uid="uid://dt1upwj08kd0w" path="res://map/grid_material.tres" id="1_w8p6k"] + +[sub_resource type="BoxMesh" id="BoxMesh_tgywu"] + +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_w8p6k"] +data = PackedVector3Array(-0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5) + +[node name="Cube" type="Node3D"] + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_tgywu") +surface_material_override/0 = ExtResource("1_w8p6k") + +[node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D"] +shape = SubResource("ConcavePolygonShape3D_w8p6k") diff --git a/map/grid_material.tres b/map/grid_material.tres new file mode 100644 index 0000000..5cdca8e --- /dev/null +++ b/map/grid_material.tres @@ -0,0 +1,10 @@ +[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://dt1upwj08kd0w"] + +[ext_resource type="Texture2D" uid="uid://c8cfruu4iw5at" path="res://texture/grid.png" id="1_h25oc"] + +[resource] +albedo_color = Color(0.46, 0.46, 0.46, 1) +albedo_texture = ExtResource("1_h25oc") +uv1_scale = Vector3(0.5, 0.5, 0.5) +uv1_triplanar = true +uv1_world_triplanar = true diff --git a/map/ramp.tscn b/map/ramp.tscn new file mode 100644 index 0000000..f5cf67b --- /dev/null +++ b/map/ramp.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=4 format=3 uid="uid://b2qh1x7ulhhua"] + +[ext_resource type="Material" uid="uid://dt1upwj08kd0w" path="res://map/grid_material.tres" id="1_pbta4"] + +[sub_resource type="PrismMesh" id="PrismMesh_nxhg3"] +size = Vector3(1, 1.78, 1) + +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_pbta4"] +data = PackedVector3Array(0, 0.89, 0.5, 0.5, -0.89, 0.5, -0.5, -0.89, 0.5, 0, 0.89, -0.5, -0.5, -0.89, -0.5, 0.5, -0.89, -0.5, 0, 0.89, 0.5, 0, 0.89, -0.5, 0.5, -0.89, 0.5, 0, 0.89, -0.5, 0.5, -0.89, -0.5, 0.5, -0.89, 0.5, 0, 0.89, -0.5, 0, 0.89, 0.5, -0.5, -0.89, -0.5, 0, 0.89, 0.5, -0.5, -0.89, 0.5, -0.5, -0.89, -0.5, -0.5, -0.89, 0.5, 0.5, -0.89, 0.5, -0.5, -0.89, -0.5, 0.5, -0.89, 0.5, 0.5, -0.89, -0.5, -0.5, -0.89, -0.5) + +[node name="Ramp" type="Node3D"] + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0) +mesh = SubResource("PrismMesh_nxhg3") +surface_material_override/0 = ExtResource("1_pbta4") + +[node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D"] +shape = SubResource("ConcavePolygonShape3D_pbta4") diff --git a/map/test.tscn b/map/test.tscn new file mode 100644 index 0000000..6bf5574 --- /dev/null +++ b/map/test.tscn @@ -0,0 +1,85 @@ +[gd_scene load_steps=15 format=3 uid="uid://cootj2rfyviyb"] + +[ext_resource type="Script" uid="uid://ccournv7m7l4y" path="res://map/Scene.gd" id="1_8uh7m"] +[ext_resource type="PackedScene" uid="uid://cchu1yltrhuk3" path="res://player/player.tscn" id="1_37kl0"] +[ext_resource type="Script" uid="uid://dd3sep8kprktl" path="res://ux/debug_overlay.gd" id="2_ykrsh"] +[ext_resource type="Script" uid="uid://mgg7ii0w4vod" path="res://ux/debug_stats.gd" id="3_g14j6"] +[ext_resource type="Script" uid="uid://bocc5xwqtbkbb" path="res://ux/debug_draw_3d.gd" id="4_g14j6"] +[ext_resource type="Material" uid="uid://dt1upwj08kd0w" path="res://map/grid_material.tres" id="6_v1i7h"] +[ext_resource type="PackedScene" uid="uid://b2qh1x7ulhhua" path="res://map/ramp.tscn" id="7_5owfa"] +[ext_resource type="PackedScene" uid="uid://iwl88y3l713o" path="res://map/cube.tscn" id="8_f4bcd"] + +[sub_resource type="Theme" id="Theme_g14j6"] +default_base_scale = 2.0 +default_font_size = 20 + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_37kl0"] +sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) +ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) + +[sub_resource type="Sky" id="Sky_8uh7m"] +sky_material = SubResource("ProceduralSkyMaterial_37kl0") + +[sub_resource type="Environment" id="Environment_6uqi0"] +background_mode = 2 +sky = SubResource("Sky_8uh7m") +tonemap_mode = 2 +glow_enabled = true + +[sub_resource type="PlaneMesh" id="PlaneMesh_mf4mk"] +size = Vector2(222, 222) + +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_37kl0"] +data = PackedVector3Array(111, 0, 111, -111, 0, 111, 111, 0, -111, -111, 0, 111, -111, 0, -111, 111, 0, -111) + +[node name="Test" type="Node3D"] +script = ExtResource("1_8uh7m") + +[node name="debug" type="CanvasLayer" parent="."] +unique_name_in_owner = true +script = ExtResource("2_ykrsh") + +[node name="DebugStats" type="MarginContainer" parent="debug"] +offset_right = 40.0 +offset_bottom = 40.0 +theme = SubResource("Theme_g14j6") +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 +script = ExtResource("3_g14j6") + +[node name="DebugDraw3D" type="Control" parent="debug"] +layout_mode = 3 +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 +script = ExtResource("4_g14j6") + +[node name="Player" parent="." instance=ExtResource("1_37kl0")] +unique_name_in_owner = true + +[node name="map" type="Node3D" parent="."] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="map"] +environment = SubResource("Environment_6uqi0") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="map"] +transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0, 0, 0) +shadow_enabled = true + +[node name="MeshInstance3D" type="MeshInstance3D" parent="map"] +mesh = SubResource("PlaneMesh_mf4mk") +skeleton = NodePath("../..") +surface_material_override/0 = ExtResource("6_v1i7h") + +[node name="StaticBody3D" type="StaticBody3D" parent="map/MeshInstance3D"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="map/MeshInstance3D/StaticBody3D"] +shape = SubResource("ConcavePolygonShape3D_37kl0") + +[node name="Ramp" parent="map" instance=ExtResource("7_5owfa")] +transform = Transform3D(-1.62606e-07, 0, -3.72, 0, 3.72, 0, 3.72, 0, -1.62606e-07, -0.137384, 0, 7.7898) + +[node name="Cube" parent="map" instance=ExtResource("8_f4bcd")] +transform = Transform3D(2.54, 0, 0, 0, 2.54, 0, 0, 0, 2.54, -7.30192, 1.27, 5.19269) diff --git a/player/CameraHandler.gd b/player/CameraHandler.gd deleted file mode 100644 index 448260f..0000000 --- a/player/CameraHandler.gd +++ /dev/null @@ -1,61 +0,0 @@ -extends Node3D -class_name CameraHandler - - -enum CameraInput {MOUSE, JOYSTICK} - -@export_range(1.0, 10.0) var camera_distance := 3.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 - - -var camera_input_method := CameraInput.MOUSE -var camera_input_direction := Vector2.ZERO -var player_input_direction := Vector2.ZERO - - -@onready var _input: InputHandler = %Input -@onready var _spring: SpringArm3D = $spring - - -# Called when the node enters the scene tree for the first time. -func _ready() -> void: - _spring.spring_length = camera_distance - - -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_camera_input_direction() - camera_input_direction *= Vector2(joystick_sensitivity_x, -joystick_sensitivity_y) - - -# Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta: float) -> void: - # vertical camera rotation - rotation.x += camera_input_direction.y * mouse_sensitivity_y * delta - rotation.x = clamp(rotation.x, -PI / 6, PI / 3) - - # horizontal camera rotation - 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 - _spring.spring_length = lerp( - _spring.spring_length, camera_distance, delta - ) diff --git a/player/CameraHandler.gd.uid b/player/CameraHandler.gd.uid deleted file mode 100644 index 846a69e..0000000 --- a/player/CameraHandler.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c5mn28v6ujngk diff --git a/player/InputHandler.gd b/player/InputHandler.gd deleted file mode 100644 index d7f2fb4..0000000 --- a/player/InputHandler.gd +++ /dev/null @@ -1,26 +0,0 @@ -extends Node -class_name InputHandler - - -func get_camera_input_direction() -> Vector2: - return Input.get_vector( - "camera-left", "camera-right", "camera-up", "camera-down" - ) - - -func get_player_input() -> InputPacket: - var p: InputPacket = InputPacket.new() - - p.movement_direction = Input.get_vector( - "player-left", "player-right", "player-forward", "player-backward" - ) - if p.movement_direction != Vector2.ZERO: - p.actions.append("walk") - - if Input.is_action_just_pressed("player-dash"): - p.actions.append("dash") - - if p.actions.is_empty(): - p.actions.append("idle") - - return p diff --git a/player/InputHandler.gd.uid b/player/InputHandler.gd.uid deleted file mode 100644 index 713eb30..0000000 --- a/player/InputHandler.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bspr3vafk6wi2 diff --git a/player/InputPacket.gd b/player/InputPacket.gd deleted file mode 100644 index e3a354f..0000000 --- a/player/InputPacket.gd +++ /dev/null @@ -1,5 +0,0 @@ -extends Node -class_name InputPacket - -var movement_direction: Vector2 = Vector2.ZERO -var actions: Array[String] = [] diff --git a/player/InputPacket.gd.uid b/player/InputPacket.gd.uid deleted file mode 100644 index 33ad24a..0000000 --- a/player/InputPacket.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cxsrxduew6xnc diff --git a/player/Move.gd b/player/Move.gd deleted file mode 100644 index 3401850..0000000 --- a/player/Move.gd +++ /dev/null @@ -1,35 +0,0 @@ -extends Node -class_name Move - -### -# flags and variables here -var player: Player -var camera: Camera3D - -# enums are prioritized by order of list -static var moves_priority: Dictionary = { - "idle": 0, - "walk": 1, - "dash": 2 -} - -static func moves_priority_sort(a: String, b: String): - return moves_priority[a] > moves_priority[b] - -### - -func should_enter(_input: InputPacket) -> String: - print_debug("Function should_enter must be implemented in its child class!") - return "" - - -func update(_input: InputPacket, _delta: float): - pass - - -func on_enter_state(): - pass - - -func on_exit_state(): - pass diff --git a/player/Move.gd.uid b/player/Move.gd.uid deleted file mode 100644 index 3a9d576..0000000 --- a/player/Move.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c886t1c86q0m6 diff --git a/player/dash.gd b/player/dash.gd deleted file mode 100644 index 6b6368f..0000000 --- a/player/dash.gd +++ /dev/null @@ -1,21 +0,0 @@ -extends Move -class_name Dash - - -func should_enter(input) -> String: - input.actions.sort_custom(moves_priority_sort) - return input.actions[0] - - -func update(input: InputPacket, _delta: float): - # Get the XZ input direction based on player's input relative to the camera - var forward := camera.global_basis.z - var right := camera.global_basis.x - var move_direction := ( - forward * input.movement_direction.y + right * input.movement_direction.x - ).normalized() - move_direction.y = 0 - - # TODO: check if new_pos is valid! - var new_pos := player.last_movement_direction * player.dash_length - player.global_position += new_pos diff --git a/player/dash.gd.uid b/player/dash.gd.uid deleted file mode 100644 index 9c00fd9..0000000 --- a/player/dash.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bdiks0m7vsn5w diff --git a/player/fall.gd b/player/fall.gd new file mode 100644 index 0000000..0119254 --- /dev/null +++ b/player/fall.gd @@ -0,0 +1,7 @@ +extends Move +class_name Fall + + +func update(_input: InputPacket, delta: float): + player.velocity += player.get_gravity() * player.acceleration * delta + player.move_and_slide() diff --git a/player/fall.gd.uid b/player/fall.gd.uid new file mode 100644 index 0000000..18ec41d --- /dev/null +++ b/player/fall.gd.uid @@ -0,0 +1 @@ +uid://b0oj5iuvr8omo diff --git a/player/idle.gd b/player/idle.gd deleted file mode 100644 index f7bd955..0000000 --- a/player/idle.gd +++ /dev/null @@ -1,15 +0,0 @@ -extends Walk -class_name Idle - - -func update(input: InputPacket, delta: float): - player.idle_time += delta - super.update(input, delta) - - -func on_enter_state(): - player.idle_time = 0.0 - - -func on_exit_state(): - player.idle_time = 0.0 diff --git a/player/idle.gd.uid b/player/idle.gd.uid deleted file mode 100644 index f14865a..0000000 --- a/player/idle.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bv5k167ugxmso diff --git a/player/input/CameraHandler.gd b/player/input/CameraHandler.gd new file mode 100644 index 0000000..448260f --- /dev/null +++ b/player/input/CameraHandler.gd @@ -0,0 +1,61 @@ +extends Node3D +class_name CameraHandler + + +enum CameraInput {MOUSE, JOYSTICK} + +@export_range(1.0, 10.0) var camera_distance := 3.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 + + +var camera_input_method := CameraInput.MOUSE +var camera_input_direction := Vector2.ZERO +var player_input_direction := Vector2.ZERO + + +@onready var _input: InputHandler = %Input +@onready var _spring: SpringArm3D = $spring + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + _spring.spring_length = camera_distance + + +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_camera_input_direction() + camera_input_direction *= Vector2(joystick_sensitivity_x, -joystick_sensitivity_y) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + # vertical camera rotation + rotation.x += camera_input_direction.y * mouse_sensitivity_y * delta + rotation.x = clamp(rotation.x, -PI / 6, PI / 3) + + # horizontal camera rotation + 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 + _spring.spring_length = lerp( + _spring.spring_length, camera_distance, delta + ) diff --git a/player/input/CameraHandler.gd.uid b/player/input/CameraHandler.gd.uid new file mode 100644 index 0000000..846a69e --- /dev/null +++ b/player/input/CameraHandler.gd.uid @@ -0,0 +1 @@ +uid://c5mn28v6ujngk diff --git a/player/input/InputHandler.gd b/player/input/InputHandler.gd new file mode 100644 index 0000000..d7f2fb4 --- /dev/null +++ b/player/input/InputHandler.gd @@ -0,0 +1,26 @@ +extends Node +class_name InputHandler + + +func get_camera_input_direction() -> Vector2: + return Input.get_vector( + "camera-left", "camera-right", "camera-up", "camera-down" + ) + + +func get_player_input() -> InputPacket: + var p: InputPacket = InputPacket.new() + + p.movement_direction = Input.get_vector( + "player-left", "player-right", "player-forward", "player-backward" + ) + if p.movement_direction != Vector2.ZERO: + p.actions.append("walk") + + if Input.is_action_just_pressed("player-dash"): + p.actions.append("dash") + + if p.actions.is_empty(): + p.actions.append("idle") + + return p diff --git a/player/input/InputHandler.gd.uid b/player/input/InputHandler.gd.uid new file mode 100644 index 0000000..713eb30 --- /dev/null +++ b/player/input/InputHandler.gd.uid @@ -0,0 +1 @@ +uid://bspr3vafk6wi2 diff --git a/player/input/InputPacket.gd b/player/input/InputPacket.gd new file mode 100644 index 0000000..e3a354f --- /dev/null +++ b/player/input/InputPacket.gd @@ -0,0 +1,5 @@ +extends Node +class_name InputPacket + +var movement_direction: Vector2 = Vector2.ZERO +var actions: Array[String] = [] diff --git a/player/input/InputPacket.gd.uid b/player/input/InputPacket.gd.uid new file mode 100644 index 0000000..33ad24a --- /dev/null +++ b/player/input/InputPacket.gd.uid @@ -0,0 +1 @@ +uid://cxsrxduew6xnc diff --git a/player/model.gd b/player/model.gd index ec1a952..c3657b0 100644 --- a/player/model.gd +++ b/player/model.gd @@ -7,7 +7,8 @@ class_name PlayerModel @onready var moves: Dictionary = { "idle": $Idle, "walk": $Walk, - "dash": $Dash + "dash": $Dash, + "fall": $Fall } var current_move: Move diff --git a/player/moves/Move.gd b/player/moves/Move.gd new file mode 100644 index 0000000..66916c4 --- /dev/null +++ b/player/moves/Move.gd @@ -0,0 +1,38 @@ +extends Node +class_name Move + +### +# flags and variables here +var player: Player +var camera: Camera3D + +# enums are prioritized by order of list +static var moves_priority: Dictionary = { + "idle": 0, + "walk": 1, + "dash": 2, + "fall": 100 +} + +static func moves_priority_sort(a: String, b: String): + return moves_priority[a] > moves_priority[b] + +### + +func should_enter(input: InputPacket) -> String: + if not player.is_on_floor(): + input.actions.append("fall") + input.actions.sort_custom(moves_priority_sort) + return input.actions[0] + + +func update(_input: InputPacket, _delta: float): + pass + + +func on_enter_state(): + pass + + +func on_exit_state(): + pass diff --git a/player/moves/Move.gd.uid b/player/moves/Move.gd.uid new file mode 100644 index 0000000..3a9d576 --- /dev/null +++ b/player/moves/Move.gd.uid @@ -0,0 +1 @@ +uid://c886t1c86q0m6 diff --git a/player/moves/dash.gd b/player/moves/dash.gd new file mode 100644 index 0000000..9ab0583 --- /dev/null +++ b/player/moves/dash.gd @@ -0,0 +1,16 @@ +extends Move +class_name Dash + + +func update(input: InputPacket, _delta: float): + # Get the XZ input direction based on player's input relative to the camera + var forward := camera.global_basis.z + var right := camera.global_basis.x + var move_direction := ( + forward * input.movement_direction.y + right * input.movement_direction.x + ).normalized() + move_direction.y = 0 + + # TODO: check if new_pos is valid! + var new_pos := player.last_movement_direction * player.dash_length + player.global_position += new_pos diff --git a/player/moves/dash.gd.uid b/player/moves/dash.gd.uid new file mode 100644 index 0000000..9c00fd9 --- /dev/null +++ b/player/moves/dash.gd.uid @@ -0,0 +1 @@ +uid://bdiks0m7vsn5w diff --git a/player/moves/idle.gd b/player/moves/idle.gd new file mode 100644 index 0000000..f7bd955 --- /dev/null +++ b/player/moves/idle.gd @@ -0,0 +1,15 @@ +extends Walk +class_name Idle + + +func update(input: InputPacket, delta: float): + player.idle_time += delta + super.update(input, delta) + + +func on_enter_state(): + player.idle_time = 0.0 + + +func on_exit_state(): + player.idle_time = 0.0 diff --git a/player/moves/idle.gd.uid b/player/moves/idle.gd.uid new file mode 100644 index 0000000..f14865a --- /dev/null +++ b/player/moves/idle.gd.uid @@ -0,0 +1 @@ +uid://bv5k167ugxmso diff --git a/player/moves/walk.gd b/player/moves/walk.gd new file mode 100644 index 0000000..cf031aa --- /dev/null +++ b/player/moves/walk.gd @@ -0,0 +1,59 @@ +extends Move +class_name Walk + + +const skin_lean_limit := PI/4 + + +func update(input: InputPacket, delta: float): + player.velocity = get_new_velocity_from_input(input, delta) + player.move_and_slide() + + # update skin rotation + var skin_target_angle := Vector3.BACK.signed_angle_to( + player.last_movement_direction, + Vector3.UP + ) + player.skin.global_rotation.y = lerp_angle( + player.skin.global_rotation.y, + skin_target_angle, + player.rotation_speed * delta + ) + + # lean into player momentum just a little bit + player.skin.rotation.z = lerp_angle( + player.skin.rotation.z, + clamp( + player.last_movement_direction.signed_angle_to( + player.velocity, Vector3.UP + ) * player.velocity.length() * 0.08, + -skin_lean_limit, skin_lean_limit + ), + player.rotation_speed * delta * 0.25 + ) + + + + +func get_new_velocity_from_input(input: InputPacket, delta: float) -> Vector3: + # Get the XZ input direction based on player's input relative to the camera + var forward := camera.global_basis.z + var right := camera.global_basis.x + var movement_direction := ( + forward * input.movement_direction.y + right * input.movement_direction.x + ).normalized() + movement_direction.y = 0 + + # save off last movement direction + if movement_direction.length() > 0.2: + player.last_movement_direction = movement_direction + + # if we're not stuck, then it's okay to set the velocity + player.floor_normal = player.get_floor_normal() + player.ground_slope_input = (PI / 2) - player.velocity.angle_to(player.floor_normal) + var new_velocity = player.velocity.move_toward( + movement_direction * (player.walk_speed + player.ground_slope_input * player.walk_speed), + player.acceleration * delta + ) + + return new_velocity diff --git a/player/moves/walk.gd.uid b/player/moves/walk.gd.uid new file mode 100644 index 0000000..7a68c1e --- /dev/null +++ b/player/moves/walk.gd.uid @@ -0,0 +1 @@ +uid://cqurhmxam2nl0 diff --git a/player/player.gd b/player/player.gd index 6f82ce6..2c6782d 100644 --- a/player/player.gd +++ b/player/player.gd @@ -5,21 +5,22 @@ class_name Player @export_group("Movement") @export var walk_speed := 8.0 @export var dash_length := 10.0 -@export var air_speed := 3.0 @export var acceleration := 20.0 @export var rotation_speed := 10.0 @export var idle_timeout := 5.0 + var idle_time := 0.00 var last_movement_direction := Vector3.ZERO var state := "" var floor_normal := Vector3.ZERO var ground_slope_input := 0.0 -@onready var _input: InputHandler = %Input -@onready var _model: PlayerModel = %Model +@onready var input: InputHandler = %Input +@onready var model: PlayerModel = %Model +@onready var skin: AnimatedSkin = %skin func _physics_process(delta: float) -> void: - var input_pkt := _input.get_player_input() - _model.update(input_pkt, delta) + var input_pkt := input.get_player_input() + model.update(input_pkt, delta) diff --git a/player/player.tscn b/player/player.tscn index fb4bbe3..0b94209 100644 --- a/player/player.tscn +++ b/player/player.tscn @@ -1,13 +1,14 @@ -[gd_scene load_steps=10 format=3 uid="uid://cchu1yltrhuk3"] +[gd_scene load_steps=11 format=3 uid="uid://cchu1yltrhuk3"] [ext_resource type="PackedScene" uid="uid://dvkx3t15l7mfb" path="res://skin/prototype_skin.tscn" id="1_4flbx"] [ext_resource type="Script" uid="uid://dcv34jq0jett0" path="res://player/player.gd" id="1_onrkg"] -[ext_resource type="Script" uid="uid://bspr3vafk6wi2" path="res://player/InputHandler.gd" id="3_g1dw6"] -[ext_resource type="Script" uid="uid://c5mn28v6ujngk" path="res://player/CameraHandler.gd" id="3_yw30f"] +[ext_resource type="Script" uid="uid://bspr3vafk6wi2" path="res://player/input/InputHandler.gd" id="3_g1dw6"] +[ext_resource type="Script" uid="uid://c5mn28v6ujngk" path="res://player/input/CameraHandler.gd" id="3_yw30f"] [ext_resource type="Script" uid="uid://bwox6frn7fmgt" path="res://player/model.gd" id="5_qjkh3"] -[ext_resource type="Script" uid="uid://bv5k167ugxmso" path="res://player/idle.gd" id="6_g6k8r"] -[ext_resource type="Script" uid="uid://cqurhmxam2nl0" path="res://player/walk.gd" id="7_rgyib"] -[ext_resource type="Script" uid="uid://bdiks0m7vsn5w" path="res://player/dash.gd" id="8_hg6s5"] +[ext_resource type="Script" uid="uid://bv5k167ugxmso" path="res://player/moves/idle.gd" id="6_g6k8r"] +[ext_resource type="Script" uid="uid://cqurhmxam2nl0" path="res://player/moves/walk.gd" id="7_rgyib"] +[ext_resource type="Script" uid="uid://bdiks0m7vsn5w" path="res://player/moves/dash.gd" id="8_hg6s5"] +[ext_resource type="Script" uid="uid://b0oj5iuvr8omo" path="res://player/fall.gd" id="9_hg6s5"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_sh265"] @@ -51,3 +52,7 @@ script = ExtResource("7_rgyib") [node name="Dash" type="Node" parent="Model"] script = ExtResource("8_hg6s5") + +[node name="Fall" type="Node" parent="Model"] +script = ExtResource("9_hg6s5") +metadata/_custom_type_script = "uid://c886t1c86q0m6" diff --git a/player/walk.gd b/player/walk.gd deleted file mode 100644 index e9cf6d9..0000000 --- a/player/walk.gd +++ /dev/null @@ -1,36 +0,0 @@ -extends Move -class_name Walk - - -func should_enter(input) -> String: - input.actions.sort_custom(moves_priority_sort) - return input.actions[0] - - -func update(input: InputPacket, delta: float): - player.velocity = get_new_velocity_from_input(input, delta) - player.move_and_slide() - - -func get_new_velocity_from_input(input: InputPacket, delta: float) -> Vector3: - # Get the XZ input direction based on player's input relative to the camera - var forward := camera.global_basis.z - var right := camera.global_basis.x - var movement_direction := ( - forward * input.movement_direction.y + right * input.movement_direction.x - ).normalized() - movement_direction.y = 0 - - # save off last movement direction - if movement_direction.length() > 0.2: - player.last_movement_direction = movement_direction - - # if we're not stuck, then it's okay to set the velocity - player.floor_normal = player.get_floor_normal() - player.ground_slope_input = (PI / 2) - player.velocity.angle_to(player.floor_normal) - var new_velocity = player.velocity.move_toward( - movement_direction * (player.walk_speed + player.ground_slope_input * player.walk_speed), - player.acceleration * delta - ) - - return new_velocity diff --git a/player/walk.gd.uid b/player/walk.gd.uid deleted file mode 100644 index 7a68c1e..0000000 --- a/player/walk.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cqurhmxam2nl0 diff --git a/test.tscn b/test.tscn deleted file mode 100644 index 8b52abd..0000000 --- a/test.tscn +++ /dev/null @@ -1,83 +0,0 @@ -[gd_scene load_steps=14 format=3 uid="uid://cootj2rfyviyb"] - -[ext_resource type="Script" uid="uid://ccournv7m7l4y" path="res://Scene.gd" id="1_8uh7m"] -[ext_resource type="PackedScene" uid="uid://cchu1yltrhuk3" path="res://player/player.tscn" id="1_37kl0"] -[ext_resource type="Texture2D" uid="uid://c8cfruu4iw5at" path="res://texture/grid.png" id="2_6uqi0"] -[ext_resource type="Script" uid="uid://dd3sep8kprktl" path="res://ux/debug_overlay.gd" id="2_ykrsh"] -[ext_resource type="Script" uid="uid://mgg7ii0w4vod" path="res://ux/debug_stats.gd" id="3_g14j6"] -[ext_resource type="Script" uid="uid://bocc5xwqtbkbb" path="res://ux/debug_draw_3d.gd" id="4_g14j6"] - -[sub_resource type="Theme" id="Theme_g14j6"] -default_base_scale = 2.0 -default_font_size = 20 - -[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_37kl0"] -sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) -ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) - -[sub_resource type="Sky" id="Sky_8uh7m"] -sky_material = SubResource("ProceduralSkyMaterial_37kl0") - -[sub_resource type="Environment" id="Environment_6uqi0"] -background_mode = 2 -sky = SubResource("Sky_8uh7m") -tonemap_mode = 2 -glow_enabled = true - -[sub_resource type="PlaneMesh" id="PlaneMesh_mf4mk"] -size = Vector2(222, 222) - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_37kl0"] -albedo_color = Color(0.46, 0.46, 0.46, 1) -albedo_texture = ExtResource("2_6uqi0") -uv1_scale = Vector3(60, 60, 60) -uv1_world_triplanar = true - -[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_37kl0"] -data = PackedVector3Array(111, 0, 111, -111, 0, 111, 111, 0, -111, -111, 0, 111, -111, 0, -111, 111, 0, -111) - -[node name="Test" type="Node3D"] -script = ExtResource("1_8uh7m") - -[node name="debug" type="CanvasLayer" parent="."] -unique_name_in_owner = true -script = ExtResource("2_ykrsh") - -[node name="DebugStats" type="MarginContainer" parent="debug"] -offset_right = 40.0 -offset_bottom = 40.0 -theme = SubResource("Theme_g14j6") -theme_override_constants/margin_left = 20 -theme_override_constants/margin_top = 20 -theme_override_constants/margin_right = 20 -theme_override_constants/margin_bottom = 20 -script = ExtResource("3_g14j6") - -[node name="DebugDraw3D" type="Control" parent="debug"] -layout_mode = 3 -anchors_preset = 0 -offset_right = 40.0 -offset_bottom = 40.0 -script = ExtResource("4_g14j6") - -[node name="Player" parent="." instance=ExtResource("1_37kl0")] -unique_name_in_owner = true - -[node name="map" type="Node3D" parent="."] - -[node name="WorldEnvironment" type="WorldEnvironment" parent="map"] -environment = SubResource("Environment_6uqi0") - -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="map"] -transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0, 0, 0) -shadow_enabled = true - -[node name="MeshInstance3D" type="MeshInstance3D" parent="map"] -mesh = SubResource("PlaneMesh_mf4mk") -skeleton = NodePath("../..") -surface_material_override/0 = SubResource("StandardMaterial3D_37kl0") - -[node name="StaticBody3D" type="StaticBody3D" parent="map/MeshInstance3D"] - -[node name="CollisionShape3D" type="CollisionShape3D" parent="map/MeshInstance3D/StaticBody3D"] -shape = SubResource("ConcavePolygonShape3D_37kl0")