diff --git a/art/fonts/DraftingMono-Regular.ttf b/art/fonts/DraftingMono-Regular.ttf new file mode 100644 index 0000000..630e91d Binary files /dev/null and b/art/fonts/DraftingMono-Regular.ttf differ diff --git a/art/fonts/DraftingMono-Regular.ttf.import b/art/fonts/DraftingMono-Regular.ttf.import new file mode 100644 index 0000000..3314bff --- /dev/null +++ b/art/fonts/DraftingMono-Regular.ttf.import @@ -0,0 +1,33 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://8guv2d1fgna7" +path="res://.godot/imported/DraftingMono-Regular.ttf-2613f107ee7cfa148009be1dfb779785.fontdata" + +[deps] + +source_file="res://art/fonts/DraftingMono-Regular.ttf" +dest_files=["res://.godot/imported/DraftingMono-Regular.ttf-2613f107ee7cfa148009be1dfb779785.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/art/tiles/target_tile.png b/art/tiles/ball_target.png similarity index 100% rename from art/tiles/target_tile.png rename to art/tiles/ball_target.png diff --git a/art/tiles/target_tile.png.import b/art/tiles/ball_target.png.import similarity index 71% rename from art/tiles/target_tile.png.import rename to art/tiles/ball_target.png.import index 451c621..3e462b4 100644 --- a/art/tiles/target_tile.png.import +++ b/art/tiles/ball_target.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://d265li1k63anm" -path="res://.godot/imported/target_tile.png-8889c881dce8d973f9cccb76e30928fa.ctex" +path="res://.godot/imported/ball_target.png-420e9ad20dd0b28420ac9e18f85c8839.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/target_tile.png" -dest_files=["res://.godot/imported/target_tile.png-8889c881dce8d973f9cccb76e30928fa.ctex"] +source_file="res://art/tiles/ball_target.png" +dest_files=["res://.godot/imported/ball_target.png-420e9ad20dd0b28420ac9e18f85c8839.ctex"] [params] diff --git a/art/tiles/destination_tile.png b/art/tiles/destination.png similarity index 100% rename from art/tiles/destination_tile.png rename to art/tiles/destination.png diff --git a/art/tiles/destination_tile.png.import b/art/tiles/destination.png.import similarity index 70% rename from art/tiles/destination_tile.png.import rename to art/tiles/destination.png.import index 69e1c3f..9eaed58 100644 --- a/art/tiles/destination_tile.png.import +++ b/art/tiles/destination.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://b7565sd31qorm" -path="res://.godot/imported/destination_tile.png-6f95af7bf74b60a839485c30677f4a21.ctex" +path="res://.godot/imported/destination.png-6d8060cc8ba13cfb8eb5a86e36773f7a.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/destination_tile.png" -dest_files=["res://.godot/imported/destination_tile.png-6f95af7bf74b60a839485c30677f4a21.ctex"] +source_file="res://art/tiles/destination.png" +dest_files=["res://.godot/imported/destination.png-6d8060cc8ba13cfb8eb5a86e36773f7a.ctex"] [params] diff --git a/art/tiles/ground_tile.png b/art/tiles/ground.png similarity index 100% rename from art/tiles/ground_tile.png rename to art/tiles/ground.png diff --git a/art/tiles/ground_tile.png.import b/art/tiles/ground.png.import similarity index 71% rename from art/tiles/ground_tile.png.import rename to art/tiles/ground.png.import index e84f7d0..c26b3db 100644 --- a/art/tiles/ground_tile.png.import +++ b/art/tiles/ground.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cm58s70te836m" -path="res://.godot/imported/ground_tile.png-a0838c31e75c33807f6e9b010d97f31b.ctex" +path="res://.godot/imported/ground.png-ce6ec90789aee5a940b6b4beb4661e80.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/ground_tile.png" -dest_files=["res://.godot/imported/ground_tile.png-a0838c31e75c33807f6e9b010d97f31b.ctex"] +source_file="res://art/tiles/ground.png" +dest_files=["res://.godot/imported/ground.png-ce6ec90789aee5a940b6b4beb4661e80.ctex"] [params] diff --git a/art/tiles/ground_bottom.png b/art/tiles/ground_bottom.png new file mode 100644 index 0000000..eaff7c3 Binary files /dev/null and b/art/tiles/ground_bottom.png differ diff --git a/art/tiles/ground_bottom.png.import b/art/tiles/ground_bottom.png.import new file mode 100644 index 0000000..248fce4 --- /dev/null +++ b/art/tiles/ground_bottom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bpa4fpmkhv6ao" +path="res://.godot/imported/ground_bottom.png-d8a2059588952b722104cd772c3c3a06.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_bottom.png" +dest_files=["res://.godot/imported/ground_bottom.png-d8a2059588952b722104cd772c3c3a06.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/ground_left.png b/art/tiles/ground_left.png new file mode 100644 index 0000000..b4ff3ed Binary files /dev/null and b/art/tiles/ground_left.png differ diff --git a/art/tiles/ground_left.png.import b/art/tiles/ground_left.png.import new file mode 100644 index 0000000..f0bd888 --- /dev/null +++ b/art/tiles/ground_left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwv5d4umos2we" +path="res://.godot/imported/ground_left.png-f29085d700bb612e942e2167f26ccb98.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_left.png" +dest_files=["res://.godot/imported/ground_left.png-f29085d700bb612e942e2167f26ccb98.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/ground_left_bottom.png b/art/tiles/ground_left_bottom.png new file mode 100644 index 0000000..1257907 Binary files /dev/null and b/art/tiles/ground_left_bottom.png differ diff --git a/art/tiles/ground_left_bottom.png.import b/art/tiles/ground_left_bottom.png.import new file mode 100644 index 0000000..8cd4f89 --- /dev/null +++ b/art/tiles/ground_left_bottom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cs7y54h6hd148" +path="res://.godot/imported/ground_left_bottom.png-ed5178aa269f950377859b107753d505.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_left_bottom.png" +dest_files=["res://.godot/imported/ground_left_bottom.png-ed5178aa269f950377859b107753d505.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/ground_right.png b/art/tiles/ground_right.png new file mode 100644 index 0000000..197feb7 Binary files /dev/null and b/art/tiles/ground_right.png differ diff --git a/art/tiles/ground_right.png.import b/art/tiles/ground_right.png.import new file mode 100644 index 0000000..1bba648 --- /dev/null +++ b/art/tiles/ground_right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cibnnq23akjqa" +path="res://.godot/imported/ground_right.png-5294f2bc13ed7d1f06582c289081850a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_right.png" +dest_files=["res://.godot/imported/ground_right.png-5294f2bc13ed7d1f06582c289081850a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/ground_right_bottom.png b/art/tiles/ground_right_bottom.png new file mode 100644 index 0000000..27a9ccd Binary files /dev/null and b/art/tiles/ground_right_bottom.png differ diff --git a/art/tiles/ground_right_bottom.png.import b/art/tiles/ground_right_bottom.png.import new file mode 100644 index 0000000..0eb1864 --- /dev/null +++ b/art/tiles/ground_right_bottom.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rc351wxc3821" +path="res://.godot/imported/ground_right_bottom.png-fd8508008a93bd4abfb6ce8b6ac148ec.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/ground_right_bottom.png" +dest_files=["res://.godot/imported/ground_right_bottom.png-fd8508008a93bd4abfb6ce8b6ac148ec.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/art/tiles/wall_tile.png b/art/tiles/wall.png similarity index 100% rename from art/tiles/wall_tile.png rename to art/tiles/wall.png diff --git a/art/tiles/wall_tile.png.import b/art/tiles/wall.png.import similarity index 72% rename from art/tiles/wall_tile.png.import rename to art/tiles/wall.png.import index 0dddfb7..90e52ed 100644 --- a/art/tiles/wall_tile.png.import +++ b/art/tiles/wall.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://lnt0clkwms52" -path="res://.godot/imported/wall_tile.png-943542e63eb98fa5c2f8ba381f7ef7b8.ctex" +path="res://.godot/imported/wall.png-b444f5cdb367a6f2116effa1c0667bcc.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://art/tiles/wall_tile.png" -dest_files=["res://.godot/imported/wall_tile.png-943542e63eb98fa5c2f8ba381f7ef7b8.ctex"] +source_file="res://art/tiles/wall.png" +dest_files=["res://.godot/imported/wall.png-b444f5cdb367a6f2116effa1c0667bcc.ctex"] [params] diff --git a/scenes/enemy.tscn b/scenes/enemy.tscn index ca4640a..1f00477 100644 --- a/scenes/enemy.tscn +++ b/scenes/enemy.tscn @@ -9,10 +9,9 @@ [sub_resource type="Animation" id="Animation_ouyrp"] length = 0.001 -[sub_resource type="Animation" id="Animation_6vdwd"] -resource_name = "idle" +[sub_resource type="Animation" id="Animation_jt5bg"] +resource_name = "hit_ball" length = 0.4 -loop_mode = 1 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true @@ -23,7 +22,7 @@ tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 1, -"values": [ExtResource("3_5xsrd")] +"values": [ExtResource("2_5t5q0")] } tracks/1/type = "value" tracks/1/imported = false @@ -50,9 +49,10 @@ tracks/2/keys = { "values": [0, 1, 2, 3] } -[sub_resource type="Animation" id="Animation_jt5bg"] -resource_name = "throw" +[sub_resource type="Animation" id="Animation_6vdwd"] +resource_name = "idle" length = 0.4 +loop_mode = 1 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true @@ -63,7 +63,7 @@ tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 1, -"values": [ExtResource("2_5t5q0")] +"values": [ExtResource("3_5xsrd")] } tracks/1/type = "value" tracks/1/imported = false @@ -134,8 +134,8 @@ tracks/2/keys = { [sub_resource type="AnimationLibrary" id="AnimationLibrary_gnukq"] _data = { "RESET": SubResource("Animation_ouyrp"), +"hit_ball": SubResource("Animation_jt5bg"), "idle": SubResource("Animation_6vdwd"), -"throw": SubResource("Animation_jt5bg"), "walk": SubResource("Animation_etqki") } @@ -172,6 +172,5 @@ shape = SubResource("RectangleShape2D_rlijp") [node name="EnemyBehaviorTree" parent="." instance=ExtResource("3_jk76t")] -[connection signal="go_to_ball" from="." to="EnemyBehaviorTree" method="_on_enemy_go_to_ball"] [connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"] [connection signal="body_exited" from="Area2D" to="." method="_on_area_2d_body_exited"] diff --git a/scenes/enemy_behavior_tree.tscn b/scenes/enemy_behavior_tree.tscn index 3554575..a20bd26 100644 --- a/scenes/enemy_behavior_tree.tscn +++ b/scenes/enemy_behavior_tree.tscn @@ -1,14 +1,10 @@ -[gd_scene load_steps=15 format=3 uid="uid://b51tdt5kunai"] +[gd_scene load_steps=11 format=3 uid="uid://b51tdt5kunai"] [ext_resource type="Script" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_b2pc4"] [ext_resource type="Script" path="res://addons/beehave/nodes/composites/sequence.gd" id="2_80fm4"] [ext_resource type="Script" path="res://addons/beehave/nodes/composites/selector.gd" id="2_xkd41"] -[ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_wait_condition.gd" id="4_0jr1a"] -[ext_resource type="Script" path="res://addons/beehave/nodes/decorators/time_limiter.gd" id="5_012bh"] -[ext_resource type="Script" path="res://scripts/enemy/behavior_tree/wait_action.gd" id="6_eyknc"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_throw_ball_condition.gd" id="7_k5qlq"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/throw_ball_action.gd" id="8_wytqf"] -[ext_resource type="Script" path="res://scripts/enemy/behavior_tree/get_random_target_action.gd" id="8_y68xp"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/can_go_to_ball_condition.gd" id="10_3puvl"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/get_ball_destination_action.gd" id="11_bvy6m"] [ext_resource type="Script" path="res://scripts/enemy/behavior_tree/move_to_destination_action.gd" id="11_tjc85"] @@ -21,28 +17,12 @@ script = ExtResource("1_b2pc4") [node name="MainSelector" type="Node" parent="."] script = ExtResource("2_xkd41") -[node name="WaitSequence" type="Node" parent="MainSelector"] -script = ExtResource("2_80fm4") - -[node name="CanWait" type="Node" parent="MainSelector/WaitSequence"] -script = ExtResource("4_0jr1a") - -[node name="TimeLimiterDecorator" type="Node" parent="MainSelector/WaitSequence"] -script = ExtResource("5_012bh") -wait_time = 2.0 - -[node name="Wait" type="Node" parent="MainSelector/WaitSequence/TimeLimiterDecorator"] -script = ExtResource("6_eyknc") - [node name="ThrowBallSequence" type="Node" parent="MainSelector"] script = ExtResource("2_80fm4") [node name="CanThrowBall" type="Node" parent="MainSelector/ThrowBallSequence"] script = ExtResource("7_k5qlq") -[node name="GetRandomTarget" type="Node" parent="MainSelector/ThrowBallSequence"] -script = ExtResource("8_y68xp") - [node name="ThrowBall" type="Node" parent="MainSelector/ThrowBallSequence"] script = ExtResource("8_wytqf") @@ -64,8 +44,5 @@ script = ExtResource("2_80fm4") [node name="CanReturnBall" type="Node" parent="MainSelector/SequenceComposite"] script = ExtResource("13_lrd2w") -[node name="GetRandomTarget2" type="Node" parent="MainSelector/SequenceComposite"] -script = ExtResource("8_y68xp") - [node name="ReturnBall" type="Node" parent="MainSelector/SequenceComposite"] script = ExtResource("14_qbh47") diff --git a/scenes/hud.tscn b/scenes/hud.tscn new file mode 100644 index 0000000..31c86b9 --- /dev/null +++ b/scenes/hud.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=3 uid="uid://bxj8v34v1igyc"] + +[ext_resource type="Script" path="res://scripts/hud.gd" id="1_glf76"] +[ext_resource type="FontFile" uid="uid://8guv2d1fgna7" path="res://art/fonts/DraftingMono-Regular.ttf" id="1_xr1ih"] + +[node name="HUD" type="CanvasLayer"] +script = ExtResource("1_glf76") + +[node name="ScoreLabel" type="Label" parent="."] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -60.0 +offset_bottom = 41.0 +grow_horizontal = 0 +theme_override_fonts/font = ExtResource("1_xr1ih") +theme_override_font_sizes/font_size = 30 +text = "0" diff --git a/scenes/main.tscn b/scenes/main.tscn index 79eec7f..d45f6d9 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -1,11 +1,14 @@ -[gd_scene load_steps=4 format=3 uid="uid://cdwgmtyq2y8sm"] +[gd_scene load_steps=6 format=3 uid="uid://cdwgmtyq2y8sm"] +[ext_resource type="Script" path="res://scripts/main.gd" id="1_1xo8b"] [ext_resource type="PackedScene" uid="uid://m8uyi35gr3qd" path="res://scenes/tile_map.tscn" id="2_c6bkg"] [ext_resource type="PackedScene" uid="uid://ba1t35yyot4jl" path="res://scenes/player.tscn" id="2_idv37"] [ext_resource type="PackedScene" uid="uid://bktg1ypaav3q3" path="res://scenes/enemy.tscn" id="3_2xcd4"] +[ext_resource type="PackedScene" uid="uid://bxj8v34v1igyc" path="res://scenes/hud.tscn" id="4_ealqo"] [node name="Main" type="Node2D"] y_sort_enabled = true +script = ExtResource("1_1xo8b") [node name="TileMap" parent="." instance=ExtResource("2_c6bkg")] position = Vector2(324, 82) @@ -19,3 +22,7 @@ position = Vector2(0, 40) z_index = 1 z_as_relative = false y_sort_enabled = true + +[node name="HUD" parent="." instance=ExtResource("4_ealqo")] + +[connection signal="hit_ball" from="TileMap/Player" to="." method="_on_player_hit_ball"] diff --git a/scenes/player.tscn b/scenes/player.tscn index 2bdd068..7c45ccd 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=17 format=3 uid="uid://ba1t35yyot4jl"] +[gd_scene load_steps=18 format=3 uid="uid://ba1t35yyot4jl"] [ext_resource type="Texture2D" uid="uid://bqkvmyqo86dtj" path="res://art/characters/Owlet_Monster_Walk_6.png" id="1_e23l4"] [ext_resource type="Script" path="res://scripts/player/player.gd" id="1_fmx2p"] @@ -8,11 +8,51 @@ [ext_resource type="Script" path="res://scripts/state_machine/state_machine.gd" id="6_hl63m"] [ext_resource type="Script" path="res://scripts/player/states/player_idle_state.gd" id="7_0nfrc"] [ext_resource type="Script" path="res://scripts/player/states/player_walk_state.gd" id="7_gcd3q"] -[ext_resource type="Script" path="res://scripts/player/states/player_throw_state.gd" id="9_atm3r"] +[ext_resource type="Script" path="res://scripts/player/states/player_hit_ball_state.gd" id="9_aqfsh"] [sub_resource type="Animation" id="Animation_rh7n7"] length = 0.001 +[sub_resource type="Animation" id="Animation_gswgu"] +resource_name = "hit_ball" +length = 0.4 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:texture") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [ExtResource("5_2s1mg")] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprite2D:hframes") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [4] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Sprite2D:frame") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 3] +} + [sub_resource type="Animation" id="Animation_7igie"] resource_name = "idle" length = 0.4 @@ -95,46 +135,6 @@ tracks/2/keys = { "values": [0, 1, 2, 3, 4, 5] } -[sub_resource type="Animation" id="Animation_gswgu"] -resource_name = "throw" -length = 0.4 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:texture") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [ExtResource("5_2s1mg")] -} -tracks/1/type = "value" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("Sprite2D:hframes") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [4] -} -tracks/2/type = "value" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath("Sprite2D:frame") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"times": PackedFloat32Array(0, 0.1, 0.2, 0.3), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 1, -"values": [0, 1, 2, 3] -} - [sub_resource type="Animation" id="Animation_pjkea"] resource_name = "walk" length = 0.6 @@ -179,17 +179,20 @@ tracks/2/keys = { [sub_resource type="AnimationLibrary" id="AnimationLibrary_ldfyt"] _data = { "RESET": SubResource("Animation_rh7n7"), +"hit_ball": SubResource("Animation_gswgu"), "idle": SubResource("Animation_7igie"), "run": SubResource("Animation_xfiuh"), -"throw": SubResource("Animation_gswgu"), "walk": SubResource("Animation_pjkea") } [sub_resource type="RectangleShape2D" id="RectangleShape2D_hocsq"] -size = Vector2(21, 10) +size = Vector2(24, 7) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_i54nm"] +size = Vector2(17, 10) [node name="Player" type="CharacterBody2D"] -collision_mask = 14 +collision_mask = 6 script = ExtResource("1_fmx2p") [node name="Sprite2D" type="Sprite2D" parent="."] @@ -204,16 +207,15 @@ libraries = { [node name="CollisionShape2D" type="CollisionShape2D" parent="."] y_sort_enabled = true -position = Vector2(-2.5, -5) +position = Vector2(-3, -3.5) shape = SubResource("RectangleShape2D_hocsq") [node name="Area2D" type="Area2D" parent="."] collision_mask = 8 [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] -y_sort_enabled = true -position = Vector2(-2.5, -5) -shape = SubResource("RectangleShape2D_hocsq") +position = Vector2(-1.5, -5) +shape = SubResource("RectangleShape2D_i54nm") [node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("state")] script = ExtResource("6_hl63m") @@ -225,9 +227,10 @@ script = ExtResource("7_0nfrc") [node name="Walk" type="Node" parent="StateMachine"] script = ExtResource("7_gcd3q") -[node name="Throw" type="Node" parent="StateMachine"] -script = ExtResource("9_atm3r") +[node name="HitBall" type="Node" parent="StateMachine"] +script = ExtResource("9_aqfsh") -[connection signal="collide_with_ball" from="." to="StateMachine/Idle" method="_on_player_collide_with_ball"] -[connection signal="animation_finished" from="AnimationPlayer" to="StateMachine/Throw" method="_on_animation_player_animation_finished"] +[connection signal="ball_starts_colliding" from="." to="StateMachine/Idle" method="_on_player_ball_starts_colliding"] +[connection signal="ball_stops_colliding" from="." to="StateMachine/Idle" method="_on_player_ball_stops_colliding"] [connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"] +[connection signal="body_exited" from="Area2D" to="." method="_on_area_2d_body_exited"] diff --git a/scenes/tile_map.tscn b/scenes/tile_map.tscn index 0a999ec..6c8b1d3 100644 --- a/scenes/tile_map.tscn +++ b/scenes/tile_map.tscn @@ -1,52 +1,123 @@ -[gd_scene load_steps=11 format=3 uid="uid://m8uyi35gr3qd"] +[gd_scene load_steps=21 format=3 uid="uid://m8uyi35gr3qd"] -[ext_resource type="Texture2D" uid="uid://cm58s70te836m" path="res://art/tiles/ground_tile.png" id="1_set62"] -[ext_resource type="Texture2D" uid="uid://lnt0clkwms52" path="res://art/tiles/wall_tile.png" id="2_iitec"] -[ext_resource type="Texture2D" uid="uid://b7565sd31qorm" path="res://art/tiles/destination_tile.png" id="3_ca0hc"] -[ext_resource type="Texture2D" uid="uid://d265li1k63anm" path="res://art/tiles/target_tile.png" id="4_w73lj"] +[ext_resource type="Texture2D" uid="uid://cm58s70te836m" path="res://art/tiles/ground.png" id="1_kvtof"] +[ext_resource type="Texture2D" uid="uid://lnt0clkwms52" path="res://art/tiles/wall.png" id="2_odoye"] +[ext_resource type="Texture2D" uid="uid://b7565sd31qorm" path="res://art/tiles/destination.png" id="3_plcvy"] +[ext_resource type="Texture2D" uid="uid://d265li1k63anm" path="res://art/tiles/ball_target.png" id="4_k2ia8"] [ext_resource type="Script" path="res://scripts/tile_map/tile_map.gd" id="5_hxvn0"] +[ext_resource type="Texture2D" uid="uid://bwv5d4umos2we" path="res://art/tiles/ground_left.png" id="5_uwsf1"] +[ext_resource type="Texture2D" uid="uid://cibnnq23akjqa" path="res://art/tiles/ground_right.png" id="6_tgb06"] +[ext_resource type="Texture2D" uid="uid://bpa4fpmkhv6ao" path="res://art/tiles/ground_bottom.png" id="7_ffh6f"] +[ext_resource type="Texture2D" uid="uid://cs7y54h6hd148" path="res://art/tiles/ground_left_bottom.png" id="8_c76ky"] +[ext_resource type="Texture2D" uid="uid://rc351wxc3821" path="res://art/tiles/ground_right_bottom.png" id="9_mdsbd"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_wq1n0"] -texture = ExtResource("1_set62") +texture = ExtResource("1_kvtof") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u0t08"] -texture = ExtResource("2_iitec") +texture = ExtResource("2_odoye") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 -0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 8.5, 0, 1.5, 15.5, 9, 0, 16) +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 9.5, -16, -7.5, 0, 0.5, 16.5, -7.5, 16.5, 9, -0.5, 17) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_x1mdb"] -texture = ExtResource("3_ca0hc") +texture = ExtResource("3_plcvy") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_hm0kl"] -texture = ExtResource("4_w73lj") +texture = ExtResource("4_k2ia8") texture_region_size = Vector2i(32, 32) 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_8npvn"] +texture = ExtResource("5_uwsf1") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-3.5, -19.5, -19.5, -11, -22.5, -13, -7, -21.5) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_f47wg"] +texture = ExtResource("6_tgb06") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(1, 0.5, 16.5, -7, 21, -4.5, 6, 3) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_trdpm"] +texture = ExtResource("7_ffh6f") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-18, -6, -2.5, 2, -6.5, 4.5, -22, -4) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_aht32"] +texture = ExtResource("8_c76ky") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-2.5, -18.5, -21, -10, -1, 1.5, -7, 2, -29, -10, -5.5, -21) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_cx4es"] +texture = ExtResource("9_mdsbd") +texture_region_size = Vector2i(32, 32) +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(16.5, -7.5, -0.5, 2, -18, -6.5, -22.5, -5, 0, 8, 21, -5.5) +0:0/0/physics_layer_1/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_1/angular_velocity = 0.0 [sub_resource type="TileSet" id="TileSet_kwgeq"] tile_shape = 1 tile_layout = 5 tile_size = Vector2i(32, 16) -physics_layer_0/collision_layer = 1 +physics_layer_0/collision_layer = 4 +physics_layer_0/collision_mask = 3 +physics_layer_1/collision_layer = 4 sources/0 = SubResource("TileSetAtlasSource_wq1n0") sources/1 = SubResource("TileSetAtlasSource_u0t08") sources/2 = SubResource("TileSetAtlasSource_x1mdb") sources/3 = SubResource("TileSetAtlasSource_hm0kl") +sources/4 = SubResource("TileSetAtlasSource_8npvn") +sources/5 = SubResource("TileSetAtlasSource_f47wg") +sources/6 = SubResource("TileSetAtlasSource_trdpm") +sources/7 = SubResource("TileSetAtlasSource_aht32") +sources/8 = SubResource("TileSetAtlasSource_cx4es") [node name="TileMap" type="TileMap"] y_sort_enabled = true +position = Vector2(-1, 1) tile_set = SubResource("TileSet_kwgeq") format = 2 layer_0/name = "ground" diff --git a/scripts/ball/ball.gd b/scripts/ball/ball.gd index bdd1208..8d12b7a 100644 --- a/scripts/ball/ball.gd +++ b/scripts/ball/ball.gd @@ -1,26 +1,43 @@ class_name Ball extends CharacterBody2D -signal notify_enemy -const Y_OFFSET = -10 +const y_offset = -10 +const player_path = "/root/Main/TileMap/Player" +const enemy_path = "/root/Main/TileMap/Enemy" +signal notify_enemy(ball_target: Vector2i) var speed = 100 var target = Vector2.ZERO @onready var tile_map: TileMap = get_parent() func _ready(): - target.y += Y_OFFSET - var player = get_node("/root/Main/TileMap/Player") - assert(player) - player.hit.connect(_on_player_hit) + target.y += y_offset + connect_player() + connect_enemy() func _physics_process(delta): position = position.move_toward(target, delta * speed) -func _on_player_hit(): - var rand_cell: Vector2i = tile_map.get_random_top_cell() - tile_map.reset_and_set_target_cell(rand_cell) - target = tile_map.map_to_local(rand_cell) + Vector2(0, Y_OFFSET) - notify_enemy.emit() +func update_target(new_target: Vector2i): + target = tile_map.map_to_local(new_target) + Vector2(0, y_offset) + # Debug + tile_map.reset_and_set_target_cell(new_target) -func aim_to_bottom() -> bool: - return tile_map.is_in_bottom_area(target) +func _on_player_hit_ball(): + var new_target: Vector2i = tile_map.get_random_top_cell() + update_target(new_target) + notify_enemy.emit(new_target) + +func _on_enemy_hit_ball(): + var new_target: Vector2i = tile_map.get_random_bottom_cell() + update_target(new_target) + notify_enemy.emit(new_target) + +func connect_player(): + var player = get_node(player_path) + assert(player) + player.hit_ball.connect(_on_player_hit_ball) + +func connect_enemy(): + var enemy = get_node(enemy_path) + assert(enemy) + enemy.hit_ball.connect(_on_enemy_hit_ball) diff --git a/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd b/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd index 2a34c61..0567af4 100644 --- a/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_go_to_ball_condition.gd @@ -2,6 +2,10 @@ class_name CanGoToBallCondition extends ConditionLeaf func tick(actor, _blackboard): - if actor.next_target != null && actor.has_thrown_ball && !actor.collide_with_ball: + if ( + actor.ball_in_game() && + actor.next_destination != null && + !actor.collide_with_ball + ): return SUCCESS return FAILURE diff --git a/scripts/enemy/behavior_tree/can_return_ball_condition.gd b/scripts/enemy/behavior_tree/can_return_ball_condition.gd index c04632a..f44d023 100644 --- a/scripts/enemy/behavior_tree/can_return_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_return_ball_condition.gd @@ -3,10 +3,9 @@ extends ConditionLeaf func tick(actor, _blackboard): if ( - actor.has_thrown_ball - && actor.next_target != null - && actor.collide_with_ball - && !actor.current_ball.aim_to_bottom() + actor.ball_in_game() && + actor.collide_with_ball && + !actor.ball_aims_to_bottom ): return SUCCESS return FAILURE diff --git a/scripts/enemy/behavior_tree/can_throw_ball_condition.gd b/scripts/enemy/behavior_tree/can_throw_ball_condition.gd index 617d059..6790f97 100644 --- a/scripts/enemy/behavior_tree/can_throw_ball_condition.gd +++ b/scripts/enemy/behavior_tree/can_throw_ball_condition.gd @@ -2,6 +2,6 @@ class_name CanThrowBallCondition extends ConditionLeaf func tick(actor, _blackboard): - if !actor.has_thrown_ball: + if !actor.ball_in_game(): return SUCCESS return FAILURE diff --git a/scripts/enemy/behavior_tree/can_wait_condition.gd b/scripts/enemy/behavior_tree/can_wait_condition.gd deleted file mode 100644 index ac9b8e0..0000000 --- a/scripts/enemy/behavior_tree/can_wait_condition.gd +++ /dev/null @@ -1,11 +0,0 @@ -class_name CanWaitCodition -extends ConditionLeaf - -func tick(actor, _blackboard): - if actor.next_target != null: - return FAILURE - - var num = randi_range(0, 1) - if num == 1: - return FAILURE - return SUCCESS diff --git a/scripts/enemy/behavior_tree/get_ball_destination_action.gd b/scripts/enemy/behavior_tree/get_ball_destination_action.gd index 9937487..25bf5e3 100644 --- a/scripts/enemy/behavior_tree/get_ball_destination_action.gd +++ b/scripts/enemy/behavior_tree/get_ball_destination_action.gd @@ -2,12 +2,5 @@ class_name GetBallDestinationAction extends ActionLeaf func tick(actor: Node, blackboard: Blackboard): -# var rand_cell: Vector2i = actor.tile_map.get_random_top_cell() -# actor.tile_map.reset_and_set_destination_cell(rand_cell) -# -# var destination = actor.tile_map.map_to_local(rand_cell) -# destination.y += actor.Y_SPAWN_OFFSET -# - blackboard.set_value("destination", actor.next_target) - + blackboard.set_value("destination", actor.next_destination) return SUCCESS diff --git a/scripts/enemy/behavior_tree/get_random_target_action.gd b/scripts/enemy/behavior_tree/get_random_target_action.gd deleted file mode 100644 index 77b4712..0000000 --- a/scripts/enemy/behavior_tree/get_random_target_action.gd +++ /dev/null @@ -1,12 +0,0 @@ -class_name GetRandomTargetAction -extends ActionLeaf - -func tick(actor, blackboard): - var rand_cell: Vector2i = actor.tile_map.get_random_bottom_cell() - actor.tile_map.reset_and_set_target_cell(rand_cell) - - var target = actor.tile_map.map_to_local(rand_cell) - - blackboard.set_value("target", target) - - return SUCCESS diff --git a/scripts/enemy/behavior_tree/move_to_destination_action.gd b/scripts/enemy/behavior_tree/move_to_destination_action.gd index 62d6d6d..d362af4 100644 --- a/scripts/enemy/behavior_tree/move_to_destination_action.gd +++ b/scripts/enemy/behavior_tree/move_to_destination_action.gd @@ -3,20 +3,20 @@ extends ActionLeaf func before_run(actor, blackboard): var destination = blackboard.get_value("destination") - actor.sprite.flip_h = actor.position.x > destination.x - actor.animation_player.play("walk") + actor.flip_sprite(destination) + actor.play_walk_animation() func tick(actor: Node, blackboard: Blackboard): var destination = blackboard.get_value("destination") - var delta = get_physics_process_delta_time() - actor.position = actor.position.move_toward(destination, delta * actor.speed) + actor.move_to(destination) if actor.position == destination: + actor.next_destination = null return SUCCESS return RUNNING func after_run(actor, blackboard): + actor.play_idle_animation() + # Debug var destination = blackboard.get_value("destination") - destination.y -= actor.Y_SPAWN_OFFSET - var cell = actor.tile_map.local_to_map(destination) - actor.tile_map.set_cell(0, cell, 0, Vector2i(0, 0), 0) # debug purpose + actor.reset_tile(destination) diff --git a/scripts/enemy/behavior_tree/return_ball_action.gd b/scripts/enemy/behavior_tree/return_ball_action.gd index a094416..bddac3d 100644 --- a/scripts/enemy/behavior_tree/return_ball_action.gd +++ b/scripts/enemy/behavior_tree/return_ball_action.gd @@ -2,15 +2,13 @@ class_name ReturnBallAction extends ActionLeaf func before_run(actor, _blackboard): - actor.play_throw_animation() + actor.play_hit_ball_animation() -func tick(actor, blackboard): - if !actor.is_throw_animation_finished: +func tick(actor, _blackboard): + if !actor.hit_ball_animation_finished: return RUNNING - else: - var target = blackboard.get_value("target") - actor.return_ball(target) - return SUCCESS + actor.return_ball() + return SUCCESS func after_run(actor, _blackboard): actor.animation_player.play("idle") diff --git a/scripts/enemy/behavior_tree/throw_ball_action.gd b/scripts/enemy/behavior_tree/throw_ball_action.gd index fb62b87..9ca768c 100644 --- a/scripts/enemy/behavior_tree/throw_ball_action.gd +++ b/scripts/enemy/behavior_tree/throw_ball_action.gd @@ -2,16 +2,13 @@ class_name ThrowBallAction extends ActionLeaf func before_run(actor, _blackboard): - actor.play_throw_animation() + actor.play_hit_ball_animation() -func tick(actor, blackboard): - if !actor.is_throw_animation_finished: +func tick(actor, _blackboard): + if !actor.hit_ball_animation_finished: return RUNNING - else: - var target = blackboard.get_value("target") - actor.throw_ball(target) - actor.has_thrown_ball = true - return SUCCESS + actor.throw_ball() + return SUCCESS func after_run(actor, _blackboard): - actor.animation_player.play("idle") + actor.play_idle_animation() diff --git a/scripts/enemy/behavior_tree/wait_action.gd b/scripts/enemy/behavior_tree/wait_action.gd deleted file mode 100644 index 9d3ea7e..0000000 --- a/scripts/enemy/behavior_tree/wait_action.gd +++ /dev/null @@ -1,8 +0,0 @@ -class_name WaitAction -extends ActionLeaf - -func before_run(actor, _blackboard): - actor.animation_player.play("idle") - -func tick(_actor, _blackboard): - return RUNNING diff --git a/scripts/enemy/enemy.gd b/scripts/enemy/enemy.gd index 4336ceb..27c4ef7 100644 --- a/scripts/enemy/enemy.gd +++ b/scripts/enemy/enemy.gd @@ -1,50 +1,76 @@ class_name Enemy extends CharacterBody2D -signal go_to_ball -const Y_SPAWN_OFFSET = -8 -@export var speed = 80 -var has_thrown_ball = false -var ball_scene = preload("res://scenes/ball.tscn") -var current_ball: Ball -var next_target +const ball_scene = preload("res://scenes/ball.tscn") +const ball_name = "Ball" +const y_spawn_offset = -8 +signal hit_ball +var speed = 80 +var next_destination var collide_with_ball = false -var is_throw_animation_finished = false +var hit_ball_animation_finished = false +var ball_aims_to_bottom = false @onready var tile_map: TileMap = get_parent() @onready var animation_player = $AnimationPlayer @onready var sprite = $Sprite2D func _ready(): - var spawn_cell: Vector2i = tile_map.get_top_spawn_cell() - position = tile_map.map_to_local(spawn_cell) - position.y += Y_SPAWN_OFFSET - animation_player.animation_finished.connect(_on_animation_finished) + var spawn_cell = tile_map.get_top_spawn_cell() + position = tile_map.map_to_local(spawn_cell) + Vector2(0, y_spawn_offset) + animation_player.animation_finished.connect(_on_hit_ball_animation_finished) -func throw_ball(target: Vector2): +func move_to(destination): + var delta = get_physics_process_delta_time() + position = position.move_toward(destination, delta * speed) + +func throw_ball(): var ball = ball_scene.instantiate() + ball.name = ball_name ball.position = position - ball.target = target + ball.notify_enemy.connect(_on_notify_enemy) tile_map.add_child(ball) - current_ball = ball - current_ball.notify_enemy.connect(_on_notify_enemy) + hit_ball.emit() -func play_throw_animation(): - is_throw_animation_finished = false +func return_ball(): + hit_ball.emit() + +func flip_sprite(destination): + sprite.flip_h = position.x > destination.x + +func play_hit_ball_animation(): + hit_ball_animation_finished = false animation_player.speed_scale = 0.8 - animation_player.play("throw") + animation_player.play("hit_ball") animation_player.speed_scale = 1 - -func return_ball(target: Vector2): - current_ball.target = target - -func _on_animation_finished(_anim_name): - is_throw_animation_finished = true -func _on_notify_enemy(): - next_target = current_ball.target +func play_idle_animation(): + animation_player.play("idle") + +func play_walk_animation(): + animation_player.play("walk") + +func _on_hit_ball_animation_finished(_anim_name): + hit_ball_animation_finished = true + +func _on_notify_enemy(ball_target: Vector2i): + if tile_map.is_in_bottom_area(ball_target): + ball_aims_to_bottom = true + else: + ball_aims_to_bottom = false + # TODO: add to ball_target an offset depending from where the enemy come from + next_destination = tile_map.map_to_local(ball_target) func _on_area_2d_body_entered(_body): collide_with_ball = true func _on_area_2d_body_exited(_body): collide_with_ball = false + +func ball_in_game() -> bool: + return tile_map.has_node(ball_name) + +# Debug functions +func reset_tile(destination): + destination.y -= y_spawn_offset + var cell = tile_map.local_to_map(destination) + tile_map.set_cell(0, cell, 0, Vector2i(0, 0), 0) diff --git a/scripts/hud.gd b/scripts/hud.gd new file mode 100644 index 0000000..85524b4 --- /dev/null +++ b/scripts/hud.gd @@ -0,0 +1,4 @@ +extends CanvasLayer + +func update_score(score): + $ScoreLabel.text = str(score) diff --git a/scripts/main.gd b/scripts/main.gd new file mode 100644 index 0000000..dd5777c --- /dev/null +++ b/scripts/main.gd @@ -0,0 +1,7 @@ +extends Node2D + +var score = 0 + +func _on_player_hit_ball(): + score += 1 + $HUD.update_score(score) diff --git a/scripts/player/player.gd b/scripts/player/player.gd index 7fa2cc0..2109876 100644 --- a/scripts/player/player.gd +++ b/scripts/player/player.gd @@ -1,21 +1,42 @@ class_name Player extends CharacterBody2D -signal hit -signal collide_with_ball +const y_spawn_offset = -8 +signal hit_ball +signal ball_starts_colliding +signal ball_stops_colliding @export var speed = 120 -var y_spawn_offset = -8 -@onready var animation_player = $AnimationPlayer -@onready var sprite = $Sprite2D @onready var tile_map: TileMap = get_parent() func _ready(): - var spawn_cell: Vector2i = tile_map.get_bottom_spawn_cell() - position = tile_map.map_to_local(spawn_cell) - position.y += y_spawn_offset + var spawn_cell = tile_map.get_bottom_spawn_cell() + position = tile_map.map_to_local(spawn_cell) + Vector2(0, y_spawn_offset) +func get_input_direction(): + return Input.get_vector("move_left", "move_right", "move_up", "move_down") -func _on_area_2d_body_entered(_body: Node2D): +func flip_sprite(): + if Input.is_action_pressed("move_left"): + $Sprite2D.flip_h = true + elif Input.is_action_pressed("move_right"): + $Sprite2D.flip_h = false + +func play_idle_animation(): + $AnimationPlayer.play("idle") + +func play_walk_animation(): + $AnimationPlayer.play("walk") + +func play_hit_ball_animation(): + $AnimationPlayer.speed_scale = 0.8 + $AnimationPlayer.play("hit_ball") + await $AnimationPlayer.animation_finished + $AnimationPlayer.speed_scale = 1 + +func _on_area_2d_body_entered(_body): # As player’s Area2D only collide with balls # We only enter this function after colliding with a ball - collide_with_ball.emit() + ball_starts_colliding.emit() + +func _on_area_2d_body_exited(_body): + ball_stops_colliding.emit() diff --git a/scripts/player/states/player_hit_ball_state.gd b/scripts/player/states/player_hit_ball_state.gd new file mode 100644 index 0000000..bf2150a --- /dev/null +++ b/scripts/player/states/player_hit_ball_state.gd @@ -0,0 +1,7 @@ +class_name PlayerHitBallState +extends PlayerState + +func enter(_msg := {}): + player.hit_ball.emit() + await player.play_hit_ball_animation() + state_machine.transition_to("Idle") diff --git a/scripts/player/states/player_idle_state.gd b/scripts/player/states/player_idle_state.gd index c8f8fbb..71ec8ec 100644 --- a/scripts/player/states/player_idle_state.gd +++ b/scripts/player/states/player_idle_state.gd @@ -1,23 +1,21 @@ class_name PlayerIdleState extends PlayerState -var collide_with_ball = false +var player_collide_with_ball = false func enter(_msg := {}): player.velocity = Vector2.ZERO - player.animation_player.play("idle") + player.play_idle_animation() func update(_delta): - if collide_with_ball && Input.is_action_pressed("hit"): - collide_with_ball = false - state_machine.transition_to("Throw") - - if get_input_direction() != Vector2.ZERO: + if player_collide_with_ball && Input.is_action_pressed("hit"): + state_machine.transition_to("HitBall") + + if player.get_input_direction() != Vector2.ZERO: state_machine.transition_to("Walk") -func get_input_direction(): - return Input.get_vector("move_left", "move_right", "move_up", "move_down") +func _on_player_ball_starts_colliding(): + player_collide_with_ball = true - -func _on_player_collide_with_ball(): - collide_with_ball = true +func _on_player_ball_stops_colliding(): + player_collide_with_ball = false diff --git a/scripts/player/states/player_throw_state.gd b/scripts/player/states/player_throw_state.gd deleted file mode 100644 index 2f4723d..0000000 --- a/scripts/player/states/player_throw_state.gd +++ /dev/null @@ -1,20 +0,0 @@ -class_name PlayerThrowState -extends PlayerState - -var is_animation_finished = false - -func enter(_msg := {}): - player.animation_player.speed_scale = 0.8 - player.animation_player.play("throw") - player.hit.emit() - -func update(_delta: float): - if is_animation_finished: - state_machine.transition_to("Idle") - -func exit(): - is_animation_finished = false - player.animation_player.speed_scale = 1 - -func _on_animation_player_animation_finished(_anim_name): - is_animation_finished = true diff --git a/scripts/player/states/player_walk_state.gd b/scripts/player/states/player_walk_state.gd index c091ea3..27de07f 100644 --- a/scripts/player/states/player_walk_state.gd +++ b/scripts/player/states/player_walk_state.gd @@ -2,25 +2,17 @@ class_name PlayerWalkState extends PlayerState func enter(_msg := {}): - player.animation_player.play("walk") + player.play_walk_animation() func physics_update(delta): - var direction = get_input_direction() + var direction = player.get_input_direction() var velocity = direction * player.speed - + + player.flip_sprite() + var collision = player.move_and_collide(velocity * delta) if collision and Input.is_action_pressed("hit"): - state_machine.transition_to("Throw") + state_machine.transition_to("HitBall") if velocity == Vector2.ZERO: state_machine.transition_to("Idle") - -func get_input_direction(): - var direction = Input.get_vector("move_left", "move_right", "move_up", "move_down") - - if Input.is_action_pressed("move_left"): - player.sprite.flip_h = true - elif Input.is_action_pressed("move_right"): - player.sprite.flip_h = false - - return direction diff --git a/scripts/tile_map/tile_map.gd b/scripts/tile_map/tile_map.gd index 275886a..167d73f 100644 --- a/scripts/tile_map/tile_map.gd +++ b/scripts/tile_map/tile_map.gd @@ -4,6 +4,11 @@ extends TileMap @export var wall_tile_source_id = 1 @export var destination_tile_source_id = 2 @export var target_tile_source_id = 3 +@export var ground_left_tile_source_id = 4 +@export var ground_right_tile_source_id = 5 +@export var ground_bottom_tile_source_id = 6 +@export var ground_left_bottom_tile_source_id = 7 +@export var ground_right_bottom_tile_source_id = 8 @export var map_width = 13 # keep to a odd value @export var map_height = 19 # keep to a odd value # Debug variables @@ -22,47 +27,59 @@ func draw_map(): draw_wall() func draw_ground(): + var tile_source_id = ground_tile_source_id + var height = get_bottom_area_height() for x in range(map_width): for y in range(map_height): - set_cell(0, Vector2i(x, y), ground_tile_source_id, Vector2i(0, 0), 0) + if x == 0 && y == map_height - 1: + tile_source_id = ground_left_bottom_tile_source_id + elif x == map_width - 1 && y == map_height - 1: + tile_source_id = ground_right_bottom_tile_source_id + elif x == 0 && y >= height.x: + tile_source_id = ground_left_tile_source_id + elif x == map_width - 1 && y >= height.x: + tile_source_id = ground_right_tile_source_id + elif y == height.y: + tile_source_id = ground_bottom_tile_source_id + else: + tile_source_id = ground_tile_source_id + set_cell(0, Vector2i(x, y), tile_source_id, Vector2i(0, 0), 0) func draw_wall(): var middle_height = floor(map_height / 2.0) for x in range(map_width): set_cell(1, Vector2i(x - 1, middle_height - 1), wall_tile_source_id, Vector2i(0, 0), 0) # why have we to add -1? -func get_top_spawn_cell(): +func get_top_spawn_cell() -> Vector2i: return Vector2i(floor(map_width / 2.0), 1) -func get_bottom_spawn_cell(): +func get_bottom_spawn_cell() -> Vector2i: return Vector2i(floor(map_width / 2.0), map_height - 2) -func get_random_top_cell(): +func get_random_top_cell() -> Vector2i: var w = get_area_width() var h = get_top_area_height() return Vector2i(randi_range(w.x, w.y), randi_range(h.x, h.y)) -func get_random_bottom_cell(): +func get_random_bottom_cell() -> Vector2i: var w = get_area_width() var h = get_bottom_area_height() return Vector2i(randi_range(w.x, w.y), randi_range(h.x, h.y)) -func is_in_bottom_area(local_position: Vector2): - var map_position = local_to_map(local_position) +func is_in_bottom_area(cell: Vector2i) -> bool: var height = get_bottom_area_height() - - return map_position.y >= height.x && map_position.y <= height.y + return cell.y >= height.x && cell.y <= height.y -func get_area_width(): +func get_area_width() -> Vector2i: return Vector2i(0, map_width - 1) -func get_top_area_height(): +func get_top_area_height() -> Vector2i: var middle_height = floor(map_height / 2.0) return Vector2i(0, middle_height - 1) -func get_bottom_area_height(): +func get_bottom_area_height() -> Vector2i: var middle_height = floor(map_height / 2.0) return Vector2i(middle_height + 1, map_height - 1)