From 20a8d4445d283661469ca714305060589a1e3b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sj=C3=B6blom?= Date: Thu, 26 Sep 2024 13:24:55 +0200 Subject: [PATCH 1/3] Added level select screen Now the players can select which level to play --- project.godot | 4 ++ scenes/levels/demo_level.tscn | 6 +- scenes/menus/death_menu.tscn | 20 +++++- scenes/menus/level_select.tscn | 127 +++++++++++++++++++++++++++++++++ scenes/menus/main_menu.tscn | 119 ++++++++++++++++++++++++++---- scripts/game_data.gd | 9 +++ scripts/game_manager.gd | 3 +- scripts/menus/death_menu.gd | 22 ++++-- scripts/menus/level_select.gd | 40 +++++++++++ scripts/menus/main_menu.gd | 10 ++- 10 files changed, 335 insertions(+), 25 deletions(-) create mode 100644 scenes/menus/level_select.tscn create mode 100644 scripts/game_data.gd create mode 100644 scripts/menus/level_select.gd diff --git a/project.godot b/project.godot index 4a0b00c..3d313d2 100644 --- a/project.godot +++ b/project.godot @@ -14,6 +14,10 @@ config/name="TDDD23-Game-Project" run/main_scene="res://scenes/menus/main_menu.tscn" config/features=PackedStringArray("4.3", "Forward Plus") +[autoload] + +game_data="*res://scripts/game_data.gd" + [file_customization] folder_colors={ diff --git a/scenes/levels/demo_level.tscn b/scenes/levels/demo_level.tscn index 69224b8..75083f6 100644 --- a/scenes/levels/demo_level.tscn +++ b/scenes/levels/demo_level.tscn @@ -58,12 +58,12 @@ position = Vector2(656, -48) [node name="bug_green_2" parent="enemies" instance=ExtResource("6_itwjh")] position = Vector2(656, 16) -[node name="collectibles" type="Node" parent="."] +[node name="cheeses" type="Node" parent="."] -[node name="cheese_1" parent="collectibles" instance=ExtResource("5_5gdem")] +[node name="cheese_1" parent="cheeses" groups=["Cheeses"] instance=ExtResource("5_5gdem")] position = Vector2(400, -16) -[node name="cheese_2" parent="collectibles" instance=ExtResource("5_5gdem")] +[node name="cheese_2" parent="cheeses" groups=["Cheeses"] instance=ExtResource("5_5gdem")] position = Vector2(656, -16) [node name="obstacles" type="Node" parent="."] diff --git a/scenes/menus/death_menu.tscn b/scenes/menus/death_menu.tscn index d3b8e10..e4d9396 100644 --- a/scenes/menus/death_menu.tscn +++ b/scenes/menus/death_menu.tscn @@ -65,6 +65,24 @@ grow_horizontal = 2 grow_vertical = 2 theme_override_fonts/font = ExtResource("1_vrx8g") theme_override_font_sizes/font_size = 32 -text = "Play Again" +text = "Restart level" + +[node name="back_button" type="Button" parent="window"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -130.0 +offset_top = 116.0 +offset_right = 130.0 +offset_bottom = 156.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("1_vrx8g") +theme_override_font_sizes/font_size = 32 +text = "Return to level select" [connection signal="pressed" from="window/restart_button" to="." method="_on_restart_button_pressed"] +[connection signal="pressed" from="window/back_button" to="." method="_on_back_button_pressed"] diff --git a/scenes/menus/level_select.tscn b/scenes/menus/level_select.tscn new file mode 100644 index 0000000..bd6bf7a --- /dev/null +++ b/scenes/menus/level_select.tscn @@ -0,0 +1,127 @@ +[gd_scene load_steps=8 format=3 uid="uid://ngm6w40hpunu"] + +[ext_resource type="FontFile" uid="uid://dwxiyviu3pln4" path="res://assets/tools/fonts/PixelOperator8.ttf" id="1_frhf3"] +[ext_resource type="Script" path="res://scripts/menus/level_select.gd" id="1_ta6or"] +[ext_resource type="FontFile" uid="uid://co7nycwx35e6j" path="res://assets/tools/fonts/PixelOperator8-Bold.ttf" id="2_ykc4w"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qki2y"] +bg_color = Color(0.878431, 0.654902, 0.262745, 1) +border_width_left = 10 +border_width_top = 10 +border_width_right = 10 +border_width_bottom = 10 +border_color = Color(0.741176, 0.466667, 0.0235294, 1) +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lmju4"] +bg_color = Color(0.7, 0.439717, 0.021, 1) +border_width_left = 10 +border_width_top = 10 +border_width_right = 10 +border_width_bottom = 10 +border_color = Color(0.7, 0.5089, 0.154, 1) +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3ditd"] +bg_color = Color(0.6, 0.372549, 0.0156863, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ini3j"] +bg_color = Color(0.88, 0.654133, 0.264, 1) +border_width_left = 10 +border_width_top = 10 +border_width_right = 10 +border_width_bottom = 10 +border_color = Color(0.742127, 0.467024, 0.0233432, 1) +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[node name="level_select" type="CanvasLayer"] +script = ExtResource("1_ta6or") + +[node name="message" type="Label" parent="."] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -572.0 +offset_top = -293.0 +offset_right = 573.0 +offset_bottom = -229.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("2_ykc4w") +theme_override_font_sizes/font_size = 49 +text = "Select which level to play!" + +[node name="item_list" type="ItemList" parent="."] +custom_minimum_size = Vector2(10, 10) +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -197.0 +offset_top = -195.0 +offset_right = 197.0 +offset_bottom = -18.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/font_color = Color(1, 1, 1, 1) +theme_override_fonts/font = ExtResource("1_frhf3") +theme_override_font_sizes/font_size = 48 +theme_override_styles/panel = SubResource("StyleBoxFlat_qki2y") + +[node name="start_button" type="Button" parent="."] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -135.5 +offset_top = 10.0 +offset_right = 135.5 +offset_bottom = 78.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("1_frhf3") +theme_override_font_sizes/font_size = 24 +theme_override_styles/hover = SubResource("StyleBoxFlat_lmju4") +theme_override_styles/pressed = SubResource("StyleBoxFlat_3ditd") +theme_override_styles/normal = SubResource("StyleBoxFlat_ini3j") +text = "Start level!" + +[node name="back_button" type="Button" parent="."] +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 29.0 +offset_top = -99.0 +offset_right = 300.0 +offset_bottom = -31.0 +grow_vertical = 0 +theme_override_fonts/font = ExtResource("1_frhf3") +theme_override_font_sizes/font_size = 24 +theme_override_styles/hover = SubResource("StyleBoxFlat_lmju4") +theme_override_styles/pressed = SubResource("StyleBoxFlat_3ditd") +theme_override_styles/normal = SubResource("StyleBoxFlat_ini3j") +text = "Return to main menu" + +[connection signal="item_selected" from="item_list" to="." method="_on_ItemList_item_selected"] +[connection signal="pressed" from="start_button" to="." method="_on_start_button_pressed"] +[connection signal="pressed" from="back_button" to="." method="_on_back_button_pressed"] diff --git a/scenes/menus/main_menu.tscn b/scenes/menus/main_menu.tscn index 142247f..74e4875 100644 --- a/scenes/menus/main_menu.tscn +++ b/scenes/menus/main_menu.tscn @@ -1,28 +1,58 @@ -[gd_scene load_steps=4 format=3 uid="uid://bnvkpndk0p0c3"] +[gd_scene load_steps=7 format=3 uid="uid://bnvkpndk0p0c3"] [ext_resource type="Script" path="res://scripts/menus/main_menu.gd" id="1_q11qb"] [ext_resource type="FontFile" uid="uid://co7nycwx35e6j" path="res://assets/tools/fonts/PixelOperator8-Bold.ttf" id="2_x5xsa"] [ext_resource type="FontFile" uid="uid://dwxiyviu3pln4" path="res://assets/tools/fonts/PixelOperator8.ttf" id="3_idsb0"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_6nlf4"] +bg_color = Color(0.7, 0.439717, 0.021, 1) +border_width_left = 10 +border_width_top = 10 +border_width_right = 10 +border_width_bottom = 10 +border_color = Color(0.7, 0.5089, 0.154, 1) +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_mdqh1"] +bg_color = Color(0.6, 0.372549, 0.0156863, 1) +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hu7by"] +bg_color = Color(0.88, 0.654133, 0.264, 1) +border_width_left = 10 +border_width_top = 10 +border_width_right = 10 +border_width_bottom = 10 +border_color = Color(0.742127, 0.467024, 0.0233432, 1) +border_blend = true +corner_radius_top_left = 10 +corner_radius_top_right = 10 +corner_radius_bottom_right = 10 +corner_radius_bottom_left = 10 + [node name="main_menu" type="CanvasLayer"] script = ExtResource("1_q11qb") [node name="message" type="Label" parent="."] -anchors_preset = 8 +anchors_preset = 5 anchor_left = 0.5 -anchor_top = 0.5 anchor_right = 0.5 -anchor_bottom = 0.5 offset_left = -561.5 -offset_top = -83.0 +offset_top = 92.0 offset_right = 561.5 -offset_bottom = 17.0 +offset_bottom = 192.0 grow_horizontal = 2 -grow_vertical = 2 size_flags_horizontal = 4 theme_override_fonts/font = ExtResource("2_x5xsa") theme_override_font_sizes/font_size = 64 -text = "Collect the cheese!" +text = "Project Stilton" horizontal_alignment = 1 vertical_alignment = 1 autowrap_mode = 2 @@ -33,14 +63,75 @@ anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 -offset_left = -136.0 -offset_top = 20.0 -offset_right = 136.0 -offset_bottom = 92.0 +offset_left = -211.0 +offset_top = -124.0 +offset_right = 211.0 +offset_bottom = -52.0 grow_horizontal = 2 grow_vertical = 2 theme_override_fonts/font = ExtResource("3_idsb0") -theme_override_font_sizes/font_size = 64 -text = "Start" +theme_override_font_sizes/font_size = 48 +theme_override_styles/hover = SubResource("StyleBoxFlat_6nlf4") +theme_override_styles/pressed = SubResource("StyleBoxFlat_mdqh1") +theme_override_styles/normal = SubResource("StyleBoxFlat_hu7by") +text = "Start game" + +[node name="load_button" type="Button" parent="."] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -211.0 +offset_top = -24.0 +offset_right = 211.0 +offset_bottom = 48.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_idsb0") +theme_override_font_sizes/font_size = 48 +theme_override_styles/hover = SubResource("StyleBoxFlat_6nlf4") +theme_override_styles/pressed = SubResource("StyleBoxFlat_mdqh1") +theme_override_styles/normal = SubResource("StyleBoxFlat_hu7by") +text = "Load game" + +[node name="options_button" type="Button" parent="."] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -211.0 +offset_top = 76.0 +offset_right = 211.0 +offset_bottom = 148.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_idsb0") +theme_override_font_sizes/font_size = 48 +theme_override_styles/hover = SubResource("StyleBoxFlat_6nlf4") +theme_override_styles/pressed = SubResource("StyleBoxFlat_mdqh1") +theme_override_styles/normal = SubResource("StyleBoxFlat_hu7by") +text = "Options" + +[node name="exit_button" type="Button" parent="."] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -211.0 +offset_top = 176.0 +offset_right = 211.0 +offset_bottom = 248.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_fonts/font = ExtResource("3_idsb0") +theme_override_font_sizes/font_size = 48 +theme_override_styles/hover = SubResource("StyleBoxFlat_6nlf4") +theme_override_styles/pressed = SubResource("StyleBoxFlat_mdqh1") +theme_override_styles/normal = SubResource("StyleBoxFlat_hu7by") +text = "Exit game" [connection signal="pressed" from="start_button" to="." method="_on_start_button_pressed"] +[connection signal="pressed" from="exit_button" to="." method="_on_exit_button_pressed"] diff --git a/scripts/game_data.gd b/scripts/game_data.gd new file mode 100644 index 0000000..f87e9d8 --- /dev/null +++ b/scripts/game_data.gd @@ -0,0 +1,9 @@ +extends Node + +var current_level_path: String = "" + +func set_current_level(path: String) -> void: + current_level_path = path + +func get_current_level() -> String: + return current_level_path diff --git a/scripts/game_manager.gd b/scripts/game_manager.gd index a3fde3d..7b5eab5 100644 --- a/scripts/game_manager.gd +++ b/scripts/game_manager.gd @@ -15,7 +15,8 @@ func _ready() -> void: call_deferred("update_initial_hud") func update_initial_hud() -> void: - player.hud.update_score(score, max_score) + if player: + player.hud.update_score(score, max_score) # Add a point for collected cheese and update HUD func add_point() -> void: diff --git a/scripts/menus/death_menu.gd b/scripts/menus/death_menu.gd index d2e6411..2870827 100644 --- a/scripts/menus/death_menu.gd +++ b/scripts/menus/death_menu.gd @@ -4,6 +4,8 @@ extends CanvasLayer @onready var death_label: Label = $window/death_label @onready var cheesy_label: Label = $window/cheesy_label @onready var restart_button: Button = $window/restart_button +@onready var back_button: Button = $window/back_button +@onready var level_select = load("res://scenes/menus/level_select.tscn") @export var fade_in_time = 1.5 @@ -13,6 +15,7 @@ func _ready(): death_label.modulate.a = opacity cheesy_label.modulate.a = opacity restart_button.modulate.a = opacity + back_button.modulate.a = opacity self.visible = false @@ -26,10 +29,21 @@ func fade_in(): tween.parallel().tween_property(death_label, "modulate:a", opacity, fade_in_time) tween.parallel().tween_property(cheesy_label, "modulate:a", opacity, fade_in_time) tween.parallel().tween_property(restart_button, "modulate:a", opacity, fade_in_time) - - + tween.parallel().tween_property(back_button, "modulate:a", opacity, fade_in_time) func _on_restart_button_pressed() -> void: Engine.time_scale = 1.0 - var game_scene = load("res://scenes/levels/game.tscn") - get_tree().change_scene_to_packed(game_scene) + + var current_level_path = game_data.get_current_level() + if current_level_path != "": + get_tree().change_scene_to_file(current_level_path) # Reload the current level + else: + print("Current level path not set") + + +func _on_back_button_pressed() -> void: + Engine.time_scale = 1.0 + if level_select: + get_tree().change_scene_to_packed(level_select) + else: + print("Failed to load main menu") diff --git a/scripts/menus/level_select.gd b/scripts/menus/level_select.gd new file mode 100644 index 0000000..03c1de3 --- /dev/null +++ b/scripts/menus/level_select.gd @@ -0,0 +1,40 @@ +extends CanvasLayer + +const LEVEL_PATHS = { + "Level 1": "res://scenes/levels/demo_level.tscn", + "Level 2": "res://scenes/levels/game.tscn", + "Level 3": "res://scenes/levels/level_3.tscn" +} + +@onready var item_list = $item_list +@onready var start_button = $start_button +@onready var main_menu = load("res://scenes/menus/main_menu.tscn") +var selected_level = "" + +func _ready() -> void: + for level_name in LEVEL_PATHS.keys(): + item_list.add_item(level_name) + + start_button.disabled = true + +func _on_ItemList_item_selected(index: int) -> void: + selected_level = item_list.get_item_text(index) + start_button.disabled = false + +func _on_start_button_pressed() -> void: + if selected_level != "": + var level_path = LEVEL_PATHS[selected_level] + var level_scene = load(level_path) + if level_scene: + game_data.set_current_level(level_path) + get_tree().change_scene_to_packed(level_scene) + else: + print("Failed to load selected level") + else: + print("No level selected") + +func _on_back_button_pressed() -> void: + if main_menu: + get_tree().change_scene_to_packed(main_menu) + else: + print("Failed to load main menu") diff --git a/scripts/menus/main_menu.gd b/scripts/menus/main_menu.gd index 4c30811..df4fef9 100644 --- a/scripts/menus/main_menu.gd +++ b/scripts/menus/main_menu.gd @@ -1,6 +1,12 @@ extends CanvasLayer -const GAME = preload("res://scenes/levels/game.tscn") +const level_select = preload("res://scenes/menus/level_select.tscn") as PackedScene func _on_start_button_pressed() -> void: - get_tree().change_scene_to_packed(GAME) + if level_select: + get_tree().change_scene_to_packed(level_select) + else: + print("Failed to load main menu") + +func _on_exit_button_pressed() -> void: + get_tree().quit() From 16fab2f6dbcefc59432996e1d51119c5347e3057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sj=C3=B6blom?= Date: Tue, 1 Oct 2024 10:32:54 +0200 Subject: [PATCH 2/3] Added pills Now the player can regain health --- assets/collectibles/pills/idle.png | Bin 0 -> 806 bytes scenes/collectibles/pill.tscn | 85 +++++++++++++++++++++++++++++ scenes/levels/game.tscn | 6 +- scripts/collectibles/pill.gd | 11 ++++ scripts/hud.gd | 11 ++-- 5 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 assets/collectibles/pills/idle.png create mode 100644 scenes/collectibles/pill.tscn create mode 100644 scripts/collectibles/pill.gd diff --git a/assets/collectibles/pills/idle.png b/assets/collectibles/pills/idle.png new file mode 100644 index 0000000000000000000000000000000000000000..0712b514d012ffeb5a88180be4fc3147cdbb0921 GIT binary patch literal 806 zcmV+>1KIqEP)Px%;7LS5RCt{2oK0@iP!xqvDwaYeI$%H~mH;cL)CI7EPR$Ue>;tJQFiR*30|o}A zODS9?v2o&`_&M*r^PYV^DN<9Z{!VV+y>|UmKnNj(5JCtcgb+dqA%qY@2s~`J_wp~t zf5i?Ue?I=&&B`FZfB$Aq006k%?Y{U5A%7nJIs?m{iQigZJM~u%{;}y}C-NX9?2iK5 zKSGrHC+r6RYeUFG^Pfs-ADrN4FFdv%SoiP0lflgFasM2B9nSGPp92^Wx8Hc!WHx>? zv)aj8_)LG3q4j2M{!WJPPk*xU4-SBdhnm(`@W=f#aN%Oiz~5PTtwy{UwtphQ>Ys_f zlc8?Dx7RO#5PySv_V*5e31=G(fE@~bgpcW$xWC!chMM$j|A_l2L#X;^;BRt-YW`UM z-T_dbWgIx$XjM^mq;msg=C`USG2{pQ?0wk&a|0-J{S)^CJp(92^RxV8SXGo}W>ytt z9pdPPu!mkuzg0zPzwbVb`U7T&>K|#o+4Xn1f|01d$>8cv)$cMXtSU-eJ$-Gy@%QB& zZa%-S_c~{%&xO};nf^gH(Cl^3X2{q-nqf-)J>0{<_BR<`eR_vqAHO-Ty%haZ2SBIz zHSL8sCqM>%d)RLA`ua_;8$jDXm?2|7;GzC?24Bq|+25PN#ht2u$^aN#fB^7w{{sMU zyW5@J-pm3d;Ri69Vd;J!^`8mb4-5>TNbaEii|zw(4dDA0&Pe{vVf&4*FT)fv^$!xU z0hs>9HowaccJ@M%fB9^G3K^LGwSM;AqmS5i59xOv0Bsn}NAd%QGpwgMV%C7@XV;(Q zU;N;6x(WdNUx0+eKDNKfLC(PPv+K|DcZN^wx`*`7*+_k@kC9T?X-A{50Sa|4WMe^D->lzrloiEEen^h8;kDZu8eK`Pb(cV$}ms kej$VqLI@#*5JKd@KU@Uj+44N$ZvX%Q07*qoM6N<$g6MXQC;$Ke literal 0 HcmV?d00001 diff --git a/scenes/collectibles/pill.tscn b/scenes/collectibles/pill.tscn new file mode 100644 index 0000000..8473a48 --- /dev/null +++ b/scenes/collectibles/pill.tscn @@ -0,0 +1,85 @@ +[gd_scene load_steps=13 format=3 uid="uid://d4bboajpgnlfq"] + +[ext_resource type="Texture2D" uid="uid://c4uxwp45gteo2" path="res://assets/collectibles/pills/idle.png" id="1_ob80m"] +[ext_resource type="Script" path="res://scripts/collectibles/pill.gd" id="1_uuhij"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_jgb45"] +atlas = ExtResource("1_ob80m") +region = Rect2(0, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_h1ywm"] +atlas = ExtResource("1_ob80m") +region = Rect2(32, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_d8ddf"] +atlas = ExtResource("1_ob80m") +region = Rect2(64, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_vuf4j"] +atlas = ExtResource("1_ob80m") +region = Rect2(96, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_okdsu"] +atlas = ExtResource("1_ob80m") +region = Rect2(128, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_x3pwa"] +atlas = ExtResource("1_ob80m") +region = Rect2(160, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_74x4m"] +atlas = ExtResource("1_ob80m") +region = Rect2(192, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_awqvx"] +atlas = ExtResource("1_ob80m") +region = Rect2(224, 0, 32, 32) + +[sub_resource type="SpriteFrames" id="SpriteFrames_kmxvc"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_jgb45") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_h1ywm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_d8ddf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_vuf4j") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_okdsu") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_x3pwa") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_74x4m") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_awqvx") +}], +"loop": true, +"name": &"idle", +"speed": 10.0 +}] + +[sub_resource type="CircleShape2D" id="CircleShape2D_ml5hj"] +radius = 8.0 + +[node name="pill" type="Area2D"] +collision_mask = 2 +script = ExtResource("1_uuhij") + +[node name="animated_sprite_pill" type="AnimatedSprite2D" parent="."] +sprite_frames = SubResource("SpriteFrames_kmxvc") +animation = &"idle" +autoplay = "idle" + +[node name="collision" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_ml5hj") + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/scenes/levels/game.tscn b/scenes/levels/game.tscn index e0712ad..688d3be 100644 --- a/scenes/levels/game.tscn +++ b/scenes/levels/game.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=17 format=4 uid="uid://b3wdmox28pm05"] +[gd_scene load_steps=18 format=4 uid="uid://b3wdmox28pm05"] [ext_resource type="Script" path="res://scripts/game_manager.gd" id="1_sqrlk"] [ext_resource type="PackedScene" uid="uid://bpw6urgdij01f" path="res://scenes/menus/win_menu.tscn" id="2_1la2g"] @@ -12,6 +12,7 @@ [ext_resource type="PackedScene" uid="uid://cagii1m6affwl" path="res://scenes/tools/tile_map_layers/decoration_layer.tscn" id="7_3xtj4"] [ext_resource type="PackedScene" uid="uid://cs03yq5n5ibww" path="res://scenes/characters/enemies/pit.tscn" id="7_5m25o"] [ext_resource type="PackedScene" uid="uid://be61rj1jagrum" path="res://scenes/characters/enemies/bug_blue.tscn" id="8_b8f1k"] +[ext_resource type="PackedScene" uid="uid://d4bboajpgnlfq" path="res://scenes/collectibles/pill.tscn" id="9_j6jwb"] [ext_resource type="PackedScene" uid="uid://dcfj1ji8t2a6c" path="res://scenes/characters/enemies/mouse_trap.tscn" id="11_p0wvp"] [ext_resource type="PackedScene" uid="uid://bw5xityvbf8d2" path="res://scenes/characters/enemies/bug_flying.tscn" id="11_soepf"] [ext_resource type="PackedScene" uid="uid://bd00qhbwn5hyd" path="res://scenes/characters/enemies/bug_flying_shooter.tscn" id="15_rs0q6"] @@ -57,6 +58,9 @@ debug_color = Color(0.961248, 0, 0.511433, 0.42) [node name="cheeses" type="Node" parent="."] +[node name="pill_1" parent="cheeses" instance=ExtResource("9_j6jwb")] +position = Vector2(48, -176) + [node name="cheese_1" parent="cheeses" groups=["Cheeses"] instance=ExtResource("6_prwsy")] position = Vector2(-16, -48) diff --git a/scripts/collectibles/pill.gd b/scripts/collectibles/pill.gd new file mode 100644 index 0000000..ab22ac8 --- /dev/null +++ b/scripts/collectibles/pill.gd @@ -0,0 +1,11 @@ +extends Area2D + +@onready var player: CharacterBody2D = %player + +func _on_body_entered(_body) -> void: + print("BODY ENTERED") + if player.current_health < player.max_health: + player.current_health += 1 + var hud = player.get_node("hud") + hud.update_health(player.current_health) + queue_free() diff --git a/scripts/hud.gd b/scripts/hud.gd index 8094c7d..4a9acfd 100644 --- a/scripts/hud.gd +++ b/scripts/hud.gd @@ -19,11 +19,14 @@ func update_health(new_health) -> void: for i in range(hearts.size()): if i < new_health: hearts[i].texture = heart_filled - elif i == new_health: - hearts[i].texture = heart_empty - bounce_heart(hearts[i]) - else: + # Bounce the heart when gaining health + if i == new_health - 1: + bounce_heart(hearts[i]) + elif i >= new_health: hearts[i].texture = heart_empty + # Bounce the heart when losing health + if i == new_health: + bounce_heart(hearts[i]) # Give a visual feedback on which heart is being removed func bounce_heart(heart: Sprite2D) -> void: From 3ca1a260ac82a996255c885f13edbe58322d9e1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sj=C3=B6blom?= Date: Fri, 4 Oct 2024 13:36:05 +0200 Subject: [PATCH 3/3] Added simplified world and level select Now there exists worlds and multiple levels. Note that this is only functionality, further work needs to be done to make it prettier! --- assets/characters/mouse/icon.png | Bin 0 -> 492 bytes project.godot | 1 + scenes/levels/demo_level.tscn | 4 +- scenes/levels/game.tscn | 4 +- scenes/menus/level_icon.tscn | 36 +++++++ scenes/menus/level_select.tscn | 127 ------------------------- scenes/menus/level_select_world_1.tscn | 76 +++++++++++++++ scenes/menus/level_select_world_2.tscn | 47 +++++++++ scenes/menus/loading_screen.tscn | 48 ++++++++++ scenes/menus/player_icon.tscn | 11 +++ scenes/menus/win_menu.tscn | 2 +- scenes/menus/world_icon.tscn | 38 ++++++++ scenes/menus/world_select.tscn | 50 ++++++++++ scripts/functions.gd | 7 ++ scripts/game_data.gd | 43 +++++++++ scripts/levels/demo_level.gd | 6 ++ scripts/levels/game.gd | 6 ++ scripts/menus/death_menu.gd | 16 ++-- scripts/menus/level_icon.gd | 17 ++++ scripts/menus/level_select.gd | 72 +++++++------- scripts/menus/loading_screen.gd | 19 ++++ scripts/menus/main_menu.gd | 2 +- scripts/menus/win_menu.gd | 7 +- scripts/menus/world_icon.gd | 15 +++ scripts/menus/world_select.gd | 34 +++++++ 25 files changed, 511 insertions(+), 177 deletions(-) create mode 100644 assets/characters/mouse/icon.png create mode 100644 scenes/menus/level_icon.tscn delete mode 100644 scenes/menus/level_select.tscn create mode 100644 scenes/menus/level_select_world_1.tscn create mode 100644 scenes/menus/level_select_world_2.tscn create mode 100644 scenes/menus/loading_screen.tscn create mode 100644 scenes/menus/player_icon.tscn create mode 100644 scenes/menus/world_icon.tscn create mode 100644 scenes/menus/world_select.tscn create mode 100644 scripts/functions.gd create mode 100644 scripts/levels/demo_level.gd create mode 100644 scripts/levels/game.gd create mode 100644 scripts/menus/level_icon.gd create mode 100644 scripts/menus/loading_screen.gd create mode 100644 scripts/menus/world_icon.gd create mode 100644 scripts/menus/world_select.gd diff --git a/assets/characters/mouse/icon.png b/assets/characters/mouse/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a89b198205453840b52845d12e951c1fcaecf7f8 GIT binary patch literal 492 zcmVPx$rb$FWR9J=Wmal8WKorNnDTCCcsj8bRGlRfHUFHJub#<|Uy6LF-x==AwF{q0l zRGynDfts?vU}{~>s%~O?m&>(jezG#i7s3T{x%YYBd+!pURjdCh)6n@vgFin#aMRFv zU64-I7a3av0IcDlmK&u3Ohf14Y+5y5eE=ZI9suIEcL3FEq7uL+-irHhHU&A71#u3p z6ad*zSpz?AFt!#TYB1B#`EGyEY6DPkvR`&V1u3%~S4AgM5CE8rZ7d^($=DXp=8F{o z!1tUoOQszla(Sdnt$aB+so(1YfN&wtegQy}19t><4BSznOnlD~P-;zZ&NH_}qd)-g z`0|Rt9i>K+H5}m9x+w$$BsD?>o8^QCB$n^?2aRl#?K2IX=K;(YEA)F^OvW}g@isRw zsY8=!qB_#O+?$Yg#j}BTAhEWa~0w2xrq2gzq` void: + var loading_screen = preload("res://scenes/menus/loading_screen.tscn").instantiate() + loading_screen.next_scene_path = target + loading_screen.parameters = parameters + get_tree().current_scene.add_child(loading_screen) diff --git a/scripts/game_data.gd b/scripts/game_data.gd index f87e9d8..b4c011d 100644 --- a/scripts/game_data.gd +++ b/scripts/game_data.gd @@ -1,9 +1,52 @@ extends Node +# Scene paths var current_level_path: String = "" +var current_world_index: int = 0 +var current_level_select_scene: PackedScene = null +# Cached references +var main_menu_scene = preload("res://scenes/menus/main_menu.tscn") +var world_select_scene = preload("res://scenes/menus/world_select.tscn") + +# Current level management func set_current_level(path: String) -> void: current_level_path = path func get_current_level() -> String: return current_level_path + +# Level select scene management +func set_level_select_scene(scene: PackedScene) -> void: + current_level_select_scene = scene + +func get_level_select_scene() -> PackedScene: + return current_level_select_scene + +func reset_level_select_scene() -> void: + current_level_select_scene = null + +# World management +func set_current_world(index: int) -> void: + current_world_index = index + +func get_current_world() -> int: + return current_world_index + +# Scene transition helpers +func transition_to_level(level_path: String) -> void: + set_current_level(level_path) + get_tree().change_scene_to_file(level_path) + +func transition_to_level_select(world_index: int, level_select: PackedScene) -> void: + set_current_world(world_index) + set_level_select_scene(level_select) + get_tree().change_scene_to_packed(level_select) + +func transition_to_world_select() -> void: + reset_level_select_scene() + get_tree().change_scene_to_packed(world_select_scene) + +func transition_to_main_menu() -> void: + reset_level_select_scene() + get_tree().change_scene_to_packed(main_menu_scene) diff --git a/scripts/levels/demo_level.gd b/scripts/levels/demo_level.gd new file mode 100644 index 0000000..4689c7a --- /dev/null +++ b/scripts/levels/demo_level.gd @@ -0,0 +1,6 @@ +extends Node2D + +var parameters: Dictionary + +func _ready() -> void: + pass diff --git a/scripts/levels/game.gd b/scripts/levels/game.gd new file mode 100644 index 0000000..4689c7a --- /dev/null +++ b/scripts/levels/game.gd @@ -0,0 +1,6 @@ +extends Node2D + +var parameters: Dictionary + +func _ready() -> void: + pass diff --git a/scripts/menus/death_menu.gd b/scripts/menus/death_menu.gd index 2870827..816d734 100644 --- a/scripts/menus/death_menu.gd +++ b/scripts/menus/death_menu.gd @@ -5,8 +5,6 @@ extends CanvasLayer @onready var cheesy_label: Label = $window/cheesy_label @onready var restart_button: Button = $window/restart_button @onready var back_button: Button = $window/back_button -@onready var level_select = load("res://scenes/menus/level_select.tscn") - @export var fade_in_time = 1.5 func _ready(): @@ -33,17 +31,17 @@ func fade_in(): func _on_restart_button_pressed() -> void: Engine.time_scale = 1.0 - - var current_level_path = game_data.get_current_level() - if current_level_path != "": - get_tree().change_scene_to_file(current_level_path) # Reload the current level + var current_level = game_data.get_current_level() + if current_level != "": + game_data.transition_to_level(current_level) else: print("Current level path not set") - func _on_back_button_pressed() -> void: Engine.time_scale = 1.0 + var level_select = game_data.get_level_select_scene() + if level_select: - get_tree().change_scene_to_packed(level_select) + game_data.transition_to_level_select(game_data.get_current_world(), level_select) else: - print("Failed to load main menu") + print("Failed to load level select menu") diff --git a/scripts/menus/level_icon.gd b/scripts/menus/level_icon.gd new file mode 100644 index 0000000..ead3140 --- /dev/null +++ b/scripts/menus/level_icon.gd @@ -0,0 +1,17 @@ +@tool +extends Control +class_name LevelIcon + +@export var level_name := "1" +@export_file("*.tscn") var next_scene_path: String +@export var next_level_up: LevelIcon +@export var next_level_down: LevelIcon +@export var next_level_left: LevelIcon +@export var next_level_right: LevelIcon + +func _ready() -> void: + $label.text = "Level " + str(level_name) + +func _process(_delta: float) -> void: + if Engine.is_editor_hint(): + $label.text = "Level " + str(level_name) diff --git a/scripts/menus/level_select.gd b/scripts/menus/level_select.gd index 03c1de3..cba7809 100644 --- a/scripts/menus/level_select.gd +++ b/scripts/menus/level_select.gd @@ -1,40 +1,42 @@ -extends CanvasLayer +extends Control +class_name LevelSelect -const LEVEL_PATHS = { - "Level 1": "res://scenes/levels/demo_level.tscn", - "Level 2": "res://scenes/levels/game.tscn", - "Level 3": "res://scenes/levels/level_3.tscn" -} - -@onready var item_list = $item_list -@onready var start_button = $start_button -@onready var main_menu = load("res://scenes/menus/main_menu.tscn") -var selected_level = "" +@onready var current_level: LevelIcon = $level_icon1 +@onready var world_select_scene = load("res://scenes/menus/world_select.tscn") +var move_tween: Tween func _ready() -> void: - for level_name in LEVEL_PATHS.keys(): - item_list.add_item(level_name) - - start_button.disabled = true - -func _on_ItemList_item_selected(index: int) -> void: - selected_level = item_list.get_item_text(index) - start_button.disabled = false + $player_icon.global_position = current_level.global_position -func _on_start_button_pressed() -> void: - if selected_level != "": - var level_path = LEVEL_PATHS[selected_level] - var level_scene = load(level_path) - if level_scene: - game_data.set_current_level(level_path) - get_tree().change_scene_to_packed(level_scene) - else: - print("Failed to load selected level") - else: - print("No level selected") +func _input(event: InputEvent) -> void: + if move_tween and move_tween.is_running(): + return + + if event.is_action_pressed("ui_left") and current_level.next_level_left: + current_level = current_level.next_level_left + tween_icon() + + if event.is_action_pressed("ui_right") and current_level.next_level_right: + current_level = current_level.next_level_right + tween_icon() + + if event.is_action_pressed("ui_up") and current_level.next_level_up: + current_level = current_level.next_level_up + tween_icon() + + if event.is_action_pressed("ui_down") and current_level.next_level_down: + current_level = current_level.next_level_down + tween_icon() + + if event.is_action_pressed("ui_cancel"): + game_data.reset_level_select_scene() + get_tree().change_scene_to_packed(world_select_scene) + + if event.is_action_pressed("ui_accept"): + if current_level.next_scene_path: + game_data.set_current_level(current_level.next_scene_path) + functions.load_screen_to_scene(current_level.next_scene_path) -func _on_back_button_pressed() -> void: - if main_menu: - get_tree().change_scene_to_packed(main_menu) - else: - print("Failed to load main menu") +func tween_icon(): + move_tween = get_tree().create_tween() + move_tween.tween_property($player_icon, "global_position", current_level.global_position, 0.5).set_trans(Tween.TRANS_SINE) diff --git a/scripts/menus/loading_screen.gd b/scripts/menus/loading_screen.gd new file mode 100644 index 0000000..c3f4c50 --- /dev/null +++ b/scripts/menus/loading_screen.gd @@ -0,0 +1,19 @@ +extends CanvasLayer + +@export_file("*.tscn") var next_scene_path: String +@export var parameters: Dictionary + +func _ready() -> void: + ResourceLoader.load_threaded_request(next_scene_path) + +func _process(_delta: float) -> void: + if ResourceLoader.load_threaded_get_status(next_scene_path) == ResourceLoader.THREAD_LOAD_LOADED: + set_process(false) + await get_tree().create_timer(1).timeout + var new_scene: PackedScene = ResourceLoader.load_threaded_get(next_scene_path) + var new_node = new_scene.instantiate() + new_node.parameters = parameters + var current_scene = get_tree().current_scene + get_tree().get_root().add_child(new_node) + get_tree().current_scene = new_node + current_scene.queue_free() diff --git a/scripts/menus/main_menu.gd b/scripts/menus/main_menu.gd index df4fef9..838d99c 100644 --- a/scripts/menus/main_menu.gd +++ b/scripts/menus/main_menu.gd @@ -1,6 +1,6 @@ extends CanvasLayer -const level_select = preload("res://scenes/menus/level_select.tscn") as PackedScene +const level_select = preload("res://scenes/menus/world_select.tscn") as PackedScene func _on_start_button_pressed() -> void: if level_select: diff --git a/scripts/menus/win_menu.gd b/scripts/menus/win_menu.gd index 987ab2c..36679e9 100644 --- a/scripts/menus/win_menu.gd +++ b/scripts/menus/win_menu.gd @@ -34,5 +34,8 @@ func _on_return_button_pressed() -> void: # Unpause the game when pressing the button get_tree().paused = false - var main_menu = load("res://scenes/menus/main_menu.tscn") - get_tree().change_scene_to_packed(main_menu) + var level_select = game_data.get_level_select_scene() + if level_select: + game_data.transition_to_level_select(game_data.get_current_world(), level_select) + else: + print("Failed to load level select menu") diff --git a/scripts/menus/world_icon.gd b/scripts/menus/world_icon.gd new file mode 100644 index 0000000..8cc799e --- /dev/null +++ b/scripts/menus/world_icon.gd @@ -0,0 +1,15 @@ +@tool +extends Control + +@export var world_index: int = 1 +@export var level_select_packed: PackedScene = load("res://scenes/menus/level_select_world_1.tscn") +@onready var level_select_scene: LevelSelect = level_select_packed.instantiate() + +func _ready() -> void: + game_data.set_current_world(world_index) + game_data.set_level_select_scene(level_select_packed) + $label.text = "World " + str(world_index) + +func _process(_delta: float) -> void: + if Engine.is_editor_hint(): + $label.text = "World " + str(world_index) diff --git a/scripts/menus/world_select.gd b/scripts/menus/world_select.gd new file mode 100644 index 0000000..6784430 --- /dev/null +++ b/scripts/menus/world_select.gd @@ -0,0 +1,34 @@ +extends Control + +@onready var worlds: Array = [$world_icon1, $world_icon2, $world_icon3, $world_icon4, $world_icon5] +@onready var main_menu_scene = load("res://scenes/menus/main_menu.tscn") +var current_world: int = 0 +var move_tween: Tween + +func _ready() -> void: + $player_icon.global_position = worlds[current_world].global_position + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("ui_left") and current_world > 0: + current_world -= 1 + tween_icon() + + if event.is_action_pressed("ui_right") and current_world < worlds.size() - 1: + current_world += 1 + tween_icon() + + if event.is_action_pressed("ui_accept"): + if worlds[current_world].level_select_packed: + game_data.set_current_world(current_world) + game_data.set_level_select_scene(worlds[current_world].level_select_packed) + get_tree().change_scene_to_packed(worlds[current_world].level_select_packed) + + if event.is_action_pressed("ui_cancel"): + if main_menu_scene: + get_tree().change_scene_to_packed(main_menu_scene) + else: + print("Failed to load main menu") + +func tween_icon(): + move_tween = get_tree().create_tween() + move_tween.tween_property($player_icon, "global_position", worlds[current_world].global_position, 0.5).set_trans(Tween.TRANS_SINE)