diff --git a/assets/textures/player/capri.png b/assets/textures/player/capri.png index 3f5b35c..c2ac482 100644 Binary files a/assets/textures/player/capri.png and b/assets/textures/player/capri.png differ diff --git a/assets/textures/player/capri.xcf b/assets/textures/player/capri.xcf new file mode 100644 index 0000000..35f1b36 Binary files /dev/null and b/assets/textures/player/capri.xcf differ diff --git a/maps/level_z.tscn b/maps/level_z.tscn index 05c748d..9a8527f 100644 --- a/maps/level_z.tscn +++ b/maps/level_z.tscn @@ -3,8 +3,8 @@ [ext_resource type="Texture2D" uid="uid://b6a7l24y30iht" path="res://assets/textures/backgrounds/chocomint.png" id="1_h5jcm"] [ext_resource type="Script" uid="uid://d3v13a4er2h1x" path="res://scripts/level/level.gd" id="1_hcs1r"] [ext_resource type="TileSet" uid="uid://xwfn24if3pxk" path="res://assets/tilesets/chocomint.tres" id="2_dj7w1"] -[ext_resource type="PackedScene" uid="uid://mh2gfm7iqqsm" path="res://objects/player/player.tscn" id="3_kyrxg"] [ext_resource type="PackedScene" uid="uid://c8r040r4glui4" path="res://objects/enemies/lashy/lashy.tscn" id="4_gykx6"] +[ext_resource type="PackedScene" uid="uid://bwtpsjpe2lf7l" path="res://objects/new_player/new_player.tscn" id="5_5v7mr"] [node name="LevelZ" type="Node2D"] script = ExtResource("1_hcs1r") @@ -22,8 +22,8 @@ use_parent_material = true tile_map_data = PackedByteArray("AAAAAAsAAAAAAAAAAAABAAsAAAAAAAAAAAACAAsAAAAAAAAAAAAHAAsAAAAAAAAAAAAIAAsAAAAAAAAAAAAJAAsAAAAAAAAAAAAKAAsAAAAAAAAAAAALAAsAAAAAAAAAAAANAAsAAAAAAAAAAAAOAAsAAAAAAAAAAAAPAAsAAAAAAAAAAAAQAAsAAAAAAAAAAAARAAsAAAAAAAAAAAADAAsAAAAAAAAAAAAEAAsAAAAAAAAAAAAFAAsAAAAAAAAAAAAGAAsAAAAAAAAAAAAMAAsAAAAAAAAAAAAFAAoAAAAAAAAAAAAGAAoAAAAAAAAAAAAGAAkAAAAAAAAAAAAHAAkAAAAAAAAAAAAIAAkAAAAAAAAAAAAJAAkAAAAAAAAAAAAKAAkAAAAAAAAAAAALAAkAAAAAAAAAAAAMAAkAAAAAAAAAAAALAAoAAAAAAAAAAAAKAAoAAAAAAAAAAAAJAAoAAAAAAAAAAAAIAAoAAAAAAAAAAAAHAAoAAAAAAAAAAAAMAAoAAAAAAAAAAAANAAoAAAAAAAAAAAAOAAoAAAAAAAAAAAAPAAoAAAAAAAAAAAAPAAkAAAAAAAAAAAAQAAkAAAAAAAAAAAAQAAgAAAAAAAAAAAAQAAcAAAAAAAAAAAAQAAYAAAAAAAAAAAARAAcAAAAAAAAAAAAQAAoAAAAAAAAAAAARAAkAAAAAAAAAAAARAAgAAAAAAAAAAAARAAoAAAAAAAAAAAARAAYAAAAAAAAAAAARAAUAAAAAAAAAAAARAAQAAAAAAAAAAAAQAAQAAAAAAAAAAAAQAAUAAAAAAAAAAAAFAAkAAAAAAAAAAAAEAAkAAAAAAAAAAAADAAkAAAAAAAAAAAACAAkAAAAAAAAAAAABAAkAAAAAAAAAAAABAAoAAAAAAAAAAAACAAoAAAAAAAAAAAADAAoAAAAAAAAAAAAEAAoAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAkAAAAAAAAAAAA=") tile_set = ExtResource("2_dj7w1") -[node name="Player" parent="." instance=ExtResource("3_kyrxg")] -position = Vector2(40, 124) - [node name="Lashy" parent="." instance=ExtResource("4_gykx6")] position = Vector2(141, 99) + +[node name="Player" parent="." instance=ExtResource("5_5v7mr")] +position = Vector2(37, 129) diff --git a/objects/new_player/new_player.gd b/objects/new_player/new_player.gd new file mode 100644 index 0000000..96d4167 --- /dev/null +++ b/objects/new_player/new_player.gd @@ -0,0 +1,77 @@ +class_name NewPlayer +extends CharacterBody2D + + +@export_group("Ground Movement") +@export var run_acceleration: float +@export var max_run_speed: float +@export var turn_acceleration: float +@export var stopping_force: float + +@export_group("Air Movement") +@export var gravity: float +@export var jump_power: float + +@export_group("Internal References") +@export var state_chart: StateChart +@export var graphics: Node2D +@export var run_animation: SpritesheetAnimation + + +var input_dir: Vector2 = Vector2.ZERO: + set(value): + input_dir = value.sign() + state_chart.set_expression_property(&"input_dir", input_dir) + + +func _physics_process(delta: float) -> void: + move_and_slide() + state_chart.set_expression_property(&"velocity", velocity) + if velocity.x != 0.0: + graphics.scale.x = signf(velocity.x) + + state_chart.set_expression_property(&"on_floor", is_on_floor()) + + input_dir = Input.get_vector(&"move_left", &"move_right", &"move_up", &"move_down") + + +func _unhandled_input(event: InputEvent) -> void: + if event.is_action_pressed(&"jump"): + state_chart.send_event(&"jump_pressed") + + +#region Idle +func _slow_to_stop(delta: float) -> void: + velocity.x = move_toward(velocity.x, 0.0, stopping_force * delta) +#endregion + +#region Running +func _apply_run_acceleration(delta: float) -> void: + if absf(velocity.x) < max_run_speed: + velocity.x += input_dir.x * run_acceleration * delta + +func _scale_run_animation(delta:float) -> void: + run_animation.speed_scale = inverse_lerp(0.0, max_run_speed, absf(velocity.x)) +#endregion + + +#region Turning +func _apply_turn_acceleration(delta: float) -> void: + velocity.x += input_dir.x * turn_acceleration * delta +#endregion + + +#region Falling +func _apply_gravity(delta: float) -> void: + velocity.y += gravity * delta +#endregion + + +#region Jumping +func _start_jump() -> void: + velocity.y = -jump_power +#endregion + + +#region Missile +#endregion diff --git a/objects/new_player/new_player.gd.uid b/objects/new_player/new_player.gd.uid new file mode 100644 index 0000000..6609e5f --- /dev/null +++ b/objects/new_player/new_player.gd.uid @@ -0,0 +1 @@ +uid://dhyi4yn0xleoy diff --git a/objects/new_player/new_player.tscn b/objects/new_player/new_player.tscn new file mode 100644 index 0000000..582d1f7 --- /dev/null +++ b/objects/new_player/new_player.tscn @@ -0,0 +1,276 @@ +[gd_scene load_steps=19 format=3 uid="uid://bwtpsjpe2lf7l"] + +[ext_resource type="Script" uid="uid://dhyi4yn0xleoy" path="res://objects/new_player/new_player.gd" id="1_xs4s5"] +[ext_resource type="Texture2D" uid="uid://c71nqfyw4a3v4" path="res://assets/textures/player/capri.png" id="3_trcll"] +[ext_resource type="Script" uid="uid://cv55s54clajw5" path="res://scripts/spritesheet_animation/spritesheet_animation.gd" id="4_bsdw5"] +[ext_resource type="Script" uid="uid://bhrh1qkv7nlyl" path="res://addons/godot_state_charts/state_chart.gd" id="5_bcjtl"] +[ext_resource type="Script" uid="uid://b11v7h3ny6kh1" path="res://addons/godot_state_charts/compound_state.gd" id="6_jnxnd"] +[ext_resource type="Script" uid="uid://rrj3six8lu8p" path="res://addons/godot_state_charts/transition.gd" id="7_rgjdc"] +[ext_resource type="Script" uid="uid://b6u7unac5srh0" path="res://addons/godot_state_charts/expression_guard.gd" id="8_8i2im"] +[ext_resource type="Script" uid="uid://cyvphy8py4ntr" path="res://addons/godot_state_charts/atomic_state.gd" id="10_mvu25"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_tvyy1"] +radius = 6.0 + +[sub_resource type="Resource" id="Resource_sfpnl"] +resource_name = "Not On Floor" +script = ExtResource("8_8i2im") +expression = "not on_floor" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_mq184"] +resource_name = "Horizontal Input" +script = ExtResource("8_8i2im") +expression = "input_dir.x != 0.0" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_nye2q"] +resource_name = "Horizontal Movement" +script = ExtResource("8_8i2im") +expression = "velocity.x != 0.0" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_n665q"] +resource_name = "No Horizontal Movement" +script = ExtResource("8_8i2im") +expression = "velocity.x == 0.0" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_8c74o"] +resource_name = "No Horizontal Input" +script = ExtResource("8_8i2im") +expression = "input_dir.x == 0.0" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_xs4s5"] +resource_name = "Opposite Input" +script = ExtResource("8_8i2im") +expression = "input_dir.x != signf(velocity.x)" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_e1cbd"] +resource_name = "Aligned Input" +script = ExtResource("8_8i2im") +expression = "input_dir.x == signf(velocity.x)" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_163ft"] +resource_name = "On Floor" +script = ExtResource("8_8i2im") +expression = "on_floor" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[sub_resource type="Resource" id="Resource_whx0j"] +resource_name = "Falling Down" +script = ExtResource("8_8i2im") +expression = "velocity.y > 0.0" +metadata/_custom_type_script = "uid://b6u7unac5srh0" + +[node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("state_chart", "graphics", "run_animation")] +collision_layer = 16 +collision_mask = 3 +floor_snap_length = 3.0 +script = ExtResource("1_xs4s5") +run_acceleration = 150.0 +max_run_speed = 100.0 +turn_acceleration = 250.0 +stopping_force = 200.0 +gravity = 450.0 +jump_power = 180.0 +state_chart = NodePath("StateChart") +graphics = NodePath("Graphics") +run_animation = NodePath("Graphics/Sprite/Run") + +[node name="CollisionShape" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_tvyy1") +debug_color = Color(3.32102e-06, 0.648976, 0.161954, 0.42) + +[node name="Graphics" type="Node2D" parent="."] + +[node name="Sprite" type="Sprite2D" parent="Graphics"] +texture = ExtResource("3_trcll") +offset = Vector2(0, -2) +hframes = 4 +vframes = 4 +region_rect = Rect2(0, 0, 64, 64) + +[node name="Idle" type="Node" parent="Graphics/Sprite"] +script = ExtResource("4_bsdw5") + +[node name="Bark" type="Node" parent="Graphics/Sprite"] +script = ExtResource("4_bsdw5") +first_frame = Vector2i(1, 0) + +[node name="Skid" type="Node" parent="Graphics/Sprite"] +script = ExtResource("4_bsdw5") +first_frame = Vector2i(2, 0) + +[node name="Run" type="Node" parent="Graphics/Sprite"] +script = ExtResource("4_bsdw5") +first_frame = Vector2i(0, 1) +frames = 4 +fps = 16.0 +loop = true + +[node name="Fall" type="Node" parent="Graphics/Sprite"] +script = ExtResource("4_bsdw5") +first_frame = Vector2i(0, 2) + +[node name="Jump" type="Node" parent="Graphics/Sprite"] +script = ExtResource("4_bsdw5") +first_frame = Vector2i(1, 2) + +[node name="Missile" type="Node" parent="Graphics/Sprite"] +script = ExtResource("4_bsdw5") +first_frame = Vector2i(2, 2) + +[node name="StateChart" type="Node" parent="."] +script = ExtResource("5_bcjtl") +track_in_editor = true +initial_expression_properties = { +&"input_dir": Vector2(0, 0), +&"on_floor": false, +&"velocity": Vector2(0, 0) +} + +[node name="Root" type="Node" parent="StateChart"] +script = ExtResource("6_jnxnd") +initial_state = NodePath("Grounded") + +[node name="Grounded" type="Node" parent="StateChart/Root"] +editor_description = "Player is standing on a floor." +script = ExtResource("6_jnxnd") +initial_state = NodePath("Standing") + +[node name="if NotOnFloor" type="Node" parent="StateChart/Root/Grounded"] +editor_description = "Transition to falling state if not touching a floor." +script = ExtResource("7_rgjdc") +to = NodePath("../../Airborne/Falling") +guard = SubResource("Resource_sfpnl") +delay_in_seconds = "0.0" + +[node name="on JumpPressed" type="Node" parent="StateChart/Root/Grounded"] +script = ExtResource("7_rgjdc") +to = NodePath("../../Airborne/Jumping") +event = &"jump_pressed" +delay_in_seconds = "0.0" + +[node name="Standing" type="Node" parent="StateChart/Root/Grounded"] +editor_description = "Player is standing still or coming to a stop." +script = ExtResource("6_jnxnd") +initial_state = NodePath("Idle") +metadata/_custom_type_script = "uid://b11v7h3ny6kh1" + +[node name="if WalkHeld" type="Node" parent="StateChart/Root/Grounded/Standing"] +editor_description = "Transition to running state if a horizontal direction is being held." +script = ExtResource("7_rgjdc") +to = NodePath("../../Running") +guard = SubResource("Resource_mq184") +delay_in_seconds = "0.0" + +[node name="Idle" type="Node" parent="StateChart/Root/Grounded/Standing"] +editor_description = "Player is stopped, standing still." +script = ExtResource("10_mvu25") + +[node name="if Moving" type="Node" parent="StateChart/Root/Grounded/Standing/Idle"] +editor_description = "Transition to stopping state if the player has horizontal velocity." +script = ExtResource("7_rgjdc") +to = NodePath("../../Stopping") +guard = SubResource("Resource_nye2q") +delay_in_seconds = "0.0" + +[node name="Stopping" type="Node" parent="StateChart/Root/Grounded/Standing"] +editor_description = "Player is slowing to a stop naturally." +script = ExtResource("10_mvu25") + +[node name="if Stopped" type="Node" parent="StateChart/Root/Grounded/Standing/Stopping"] +editor_description = "Transition to idle state when the player has come to a full stop." +script = ExtResource("7_rgjdc") +to = NodePath("../../Idle") +guard = SubResource("Resource_n665q") +delay_in_seconds = "0.0" + +[node name="Running" type="Node" parent="StateChart/Root/Grounded"] +editor_description = "Player is accelerating in the held input direction." +script = ExtResource("10_mvu25") + +[node name="if WalkReleased" type="Node" parent="StateChart/Root/Grounded/Running"] +editor_description = "Transition to standing state if no input direction is held." +script = ExtResource("7_rgjdc") +to = NodePath("../../Standing") +guard = SubResource("Resource_8c74o") +delay_in_seconds = "0.0" + +[node name="if OppositeInput" type="Node" parent="StateChart/Root/Grounded/Running"] +editor_description = "Transition to turning state if the held input dir is opposite the horizontal velocity." +script = ExtResource("7_rgjdc") +to = NodePath("../../Turning") +guard = SubResource("Resource_xs4s5") +delay_in_seconds = "0.0" + +[node name="Turning" type="Node" parent="StateChart/Root/Grounded"] +editor_description = "Player is more quickly accelerating in the held input direction to slow and turn around." +script = ExtResource("10_mvu25") + +[node name="if WalkReleased" type="Node" parent="StateChart/Root/Grounded/Turning"] +editor_description = "Transition to standing state if no input direction is held." +script = ExtResource("7_rgjdc") +to = NodePath("../../Standing") +guard = SubResource("Resource_8c74o") +delay_in_seconds = "0.0" + +[node name="if AlignedInput" type="Node" parent="StateChart/Root/Grounded/Turning"] +editor_description = "Transition to running state when input direction matches horizontal velocity." +script = ExtResource("7_rgjdc") +to = NodePath("../../Running") +guard = SubResource("Resource_e1cbd") +delay_in_seconds = "0.0" + +[node name="Airborne" type="Node" parent="StateChart/Root"] +editor_description = "Player is in the air." +script = ExtResource("6_jnxnd") +initial_state = NodePath("Falling") + +[node name="if OnFloor" type="Node" parent="StateChart/Root/Airborne"] +editor_description = "Transition to grounded state if touching a floor." +script = ExtResource("7_rgjdc") +to = NodePath("../../Grounded") +guard = SubResource("Resource_163ft") +delay_in_seconds = "0.0" + +[node name="Falling" type="Node" parent="StateChart/Root/Airborne"] +editor_description = "Player is falling down." +script = ExtResource("10_mvu25") + +[node name="Jumping" type="Node" parent="StateChart/Root/Airborne"] +editor_description = "Player has jumped and is rising." +script = ExtResource("10_mvu25") + +[node name="if DownVelocity" type="Node" parent="StateChart/Root/Airborne/Jumping"] +editor_description = "Transition to the falling state if moving downwards." +script = ExtResource("7_rgjdc") +to = NodePath("../../Falling") +guard = SubResource("Resource_whx0j") +delay_in_seconds = "0.0" + +[node name="Missile" type="Node" parent="StateChart/Root/Airborne"] +editor_description = "Player is hurtling through the air and ricocheting off of surfaces." +script = ExtResource("10_mvu25") + +[node name="Voice" type="AudioStreamPlayer" parent="."] +bus = &"Capri" + +[connection signal="state_entered" from="StateChart/Root/Grounded/Standing/Idle" to="Graphics/Sprite/Idle" method="play"] +[connection signal="state_entered" from="StateChart/Root/Grounded/Standing/Stopping" to="Graphics/Sprite/Run" method="play"] +[connection signal="state_physics_processing" from="StateChart/Root/Grounded/Standing/Stopping" to="." method="_scale_run_animation"] +[connection signal="state_physics_processing" from="StateChart/Root/Grounded/Standing/Stopping" to="." method="_slow_to_stop"] +[connection signal="state_entered" from="StateChart/Root/Grounded/Running" to="Graphics/Sprite/Run" method="play"] +[connection signal="state_physics_processing" from="StateChart/Root/Grounded/Running" to="." method="_scale_run_animation"] +[connection signal="state_physics_processing" from="StateChart/Root/Grounded/Running" to="." method="_apply_run_acceleration"] +[connection signal="state_entered" from="StateChart/Root/Grounded/Turning" to="Graphics/Sprite/Skid" method="play"] +[connection signal="state_physics_processing" from="StateChart/Root/Grounded/Turning" to="." method="_apply_turn_acceleration"] +[connection signal="state_physics_processing" from="StateChart/Root/Airborne" to="." method="_apply_gravity"] +[connection signal="state_entered" from="StateChart/Root/Airborne/Falling" to="Graphics/Sprite/Fall" method="play"] +[connection signal="state_entered" from="StateChart/Root/Airborne/Jumping" to="." method="_start_jump"] +[connection signal="state_entered" from="StateChart/Root/Airborne/Jumping" to="Graphics/Sprite/Jump" method="play"] +[connection signal="state_entered" from="StateChart/Root/Airborne/Missile" to="Graphics/Sprite/Missile" method="play"] diff --git a/project.godot b/project.godot index 958a0c3..f53d2d3 100644 --- a/project.godot +++ b/project.godot @@ -11,7 +11,7 @@ config_version=5 [application] config/name="Capri" -run/main_scene="res://maps/tutorial.tscn" +run/main_scene="uid://cccb8wltupasj" config/features=PackedStringArray("4.4", "GL Compatibility") config/icon="res://icon.svg" @@ -27,7 +27,7 @@ window/size/viewport_height=216 [editor_plugins] -enabled=PackedStringArray("res://addons/YouCanDoIt/plugin.cfg", "res://addons/godot_state_charts/plugin.cfg") +enabled=PackedStringArray("res://addons/godot_state_charts/plugin.cfg") [file_customization] @@ -44,6 +44,34 @@ folder_colors={ screen_overlay="Autoload that will be rendered over the game viewport at full resolution." +[input] + +move_left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +move_up={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +move_down={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":90,"key_label":0,"unicode":122,"location":0,"echo":false,"script":null) +] +} + [layer_names] 2d_physics/layer_1="solid"