From 7c3d95aa9f6b47c0c6393cfecac0aaca8f1ae6ca Mon Sep 17 00:00:00 2001 From: Meik <2212733@stud.hs-mannheim.de> Date: Sat, 27 Jun 2026 16:08:00 +0200 Subject: [PATCH] implemented achievement system with screen and unlockables --- project.godot | 1 + scenes/achievements_screen.tscn | 182 +++++++++++++++++++++++++++ scenes/game.gd | 1 + scenes/mainmenu.tscn | 52 +++++--- scripts/achievement_manager.gd | 193 +++++++++++++++++++++++++++++ scripts/achievement_manager.gd.uid | 1 + scripts/achievements_screen.gd | 89 +++++++++++++ scripts/achievements_screen.gd.uid | 1 + scripts/mainmenu.gd | 3 + scripts/pause_menu.gd | 1 + 10 files changed, 507 insertions(+), 17 deletions(-) create mode 100644 scenes/achievements_screen.tscn create mode 100644 scripts/achievement_manager.gd create mode 100644 scripts/achievement_manager.gd.uid create mode 100644 scripts/achievements_screen.gd create mode 100644 scripts/achievements_screen.gd.uid diff --git a/project.godot b/project.godot index bf07853..d71621d 100644 --- a/project.godot +++ b/project.godot @@ -24,6 +24,7 @@ buses/default_bus_layout="uid://5oswo22yvmtg" MusicManager="*uid://dmu7041wi1upt" SpellLibrary="*res://scripts/SpellLibrary.gd" StatsManager="*res://scripts/stats_manager.gd" +AchievementManager="*res://scripts/achievement_manager.gd" [display] diff --git a/scenes/achievements_screen.tscn b/scenes/achievements_screen.tscn new file mode 100644 index 0000000..206dc15 --- /dev/null +++ b/scenes/achievements_screen.tscn @@ -0,0 +1,182 @@ +[gd_scene format=3] + +[ext_resource type="Script" path="res://scripts/achievements_screen.gd" id="1_ach"] +[ext_resource type="Texture2D" uid="uid://2ddggeetjj1t" path="res://assets/images/screenshot_game.png" id="2_ach"] +[ext_resource type="FontFile" uid="uid://8v71dcws4q6o" path="res://assets/fonts/slkscre.ttf" id="3_ach"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_info"] +bg_color = Color(0.04, 0.04, 0.1, 0.9) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.4, 0.3, 0.1, 0.8) +content_margin_left = 10.0 +content_margin_top = 8.0 +content_margin_right = 10.0 +content_margin_bottom = 8.0 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_normal"] +content_margin_left = 10.0 +content_margin_top = 4.0 +content_margin_right = 10.0 +content_margin_bottom = 4.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_hover"] +bg_color = Color(0.45, 0.1, 0.7, 0.35) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.75, 0.45, 1.0, 0.75) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +content_margin_left = 10.0 +content_margin_top = 4.0 +content_margin_right = 10.0 +content_margin_bottom = 4.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pressed"] +bg_color = Color(0.3, 0.05, 0.5, 0.55) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.9, 0.6, 1.0, 1.0) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +content_margin_left = 10.0 +content_margin_top = 4.0 +content_margin_right = 10.0 +content_margin_bottom = 4.0 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_focus"] +content_margin_left = 10.0 +content_margin_top = 4.0 +content_margin_right = 10.0 +content_margin_bottom = 4.0 + +[node name="AchievementsScreen" type="CanvasLayer"] +script = ExtResource("1_ach") + +[node name="BackgroundSprite" type="TextureRect" parent="."] +z_index = -2 +offset_left = 4.0 +offset_top = 2.0 +offset_right = 1277.0 +offset_bottom = 718.0 +texture = ExtResource("2_ach") +expand_mode = 2 + +[node name="BackgroundRect" type="ColorRect" parent="."] +z_index = -1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 0, 0, 0.6) + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +z_index = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -308.5 +offset_top = -300.0 +offset_right = 308.5 +offset_bottom = 300.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 10 +alignment = 1 + +[node name="TitleLabel" type="Label" parent="VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(1, 0.9, 0.6, 1) +theme_override_colors/font_outline_color = Color(0.4, 0.05, 0.65, 1) +theme_override_constants/outline_size = 3 +theme_override_fonts/font = ExtResource("3_ach") +theme_override_font_sizes/font_size = 56 +text = "Achievements" +horizontal_alignment = 1 + +[node name="CounterLabel" type="Label" parent="VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.9, 0.85, 0.75, 1) +theme_override_fonts/font = ExtResource("3_ach") +theme_override_font_sizes/font_size = 20 +text = "Unlocked: 0 of 10" +horizontal_alignment = 1 + +[node name="Spacer1" type="Control" parent="VBoxContainer"] +layout_mode = 2 +custom_minimum_size = Vector2(0, 8) + +[node name="AchievementGrid" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_constants/h_separation = 6 +theme_override_constants/v_separation = 6 +columns = 5 + +[node name="Spacer2" type="Control" parent="VBoxContainer"] +layout_mode = 2 +custom_minimum_size = Vector2(0, 8) + +[node name="InfoPanel" type="PanelContainer" parent="VBoxContainer"] +custom_minimum_size = Vector2(0, 72) +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_info") + +[node name="InfoVBox" type="VBoxContainer" parent="VBoxContainer/InfoPanel"] +layout_mode = 2 +theme_override_constants/separation = 2 + +[node name="InfoTitle" type="Label" parent="VBoxContainer/InfoPanel/InfoVBox"] +layout_mode = 2 +theme_override_fonts/font = ExtResource("3_ach") +theme_override_font_sizes/font_size = 20 +theme_override_colors/font_color = Color(1, 1, 0.55, 1) + +[node name="InfoDesc" type="Label" parent="VBoxContainer/InfoPanel/InfoVBox"] +layout_mode = 2 +theme_override_fonts/font = ExtResource("3_ach") +theme_override_font_sizes/font_size = 16 +theme_override_colors/font_color = Color(0.9, 0.85, 0.75, 1) +text = "Hover over an achievement to see details." + +[node name="InfoReward" type="Label" parent="VBoxContainer/InfoPanel/InfoVBox"] +layout_mode = 2 +theme_override_fonts/font = ExtResource("3_ach") +theme_override_font_sizes/font_size = 16 +theme_override_colors/font_color = Color(0.75, 0.45, 1.0, 1) + +[node name="Spacer3" type="Control" parent="VBoxContainer"] +layout_mode = 2 +custom_minimum_size = Vector2(0, 8) + +[node name="BackButton" type="Button" parent="VBoxContainer"] +custom_minimum_size = Vector2(250, 50) +layout_mode = 2 +theme_override_colors/font_color = Color(1, 0.95, 0.8, 1) +theme_override_colors/font_hover_color = Color(1, 1, 0.55, 1) +theme_override_colors/font_pressed_color = Color(1, 1, 0.75, 1) +theme_override_colors/font_focus_color = Color(1, 0.95, 0.8, 1) +theme_override_fonts/font = ExtResource("3_ach") +theme_override_font_sizes/font_size = 32 +theme_override_styles/normal = SubResource("StyleBoxEmpty_normal") +theme_override_styles/hover = SubResource("StyleBoxFlat_hover") +theme_override_styles/pressed = SubResource("StyleBoxFlat_pressed") +theme_override_styles/focus = SubResource("StyleBoxEmpty_focus") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_normal") +theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_pressed") +text = "Back" + +[connection signal="pressed" from="VBoxContainer/BackButton" to="." method="_on_back_button_pressed"] diff --git a/scenes/game.gd b/scenes/game.gd index 8a75d6f..a61f22d 100644 --- a/scenes/game.gd +++ b/scenes/game.gd @@ -18,6 +18,7 @@ func _process(_delta: float) -> void: func _on_witch_died(killer) -> void: StatsManager.end_run(true) + AchievementManager.check_all() var witch = $World/Witch var player = $World/Player $PauseMenu.process_mode = Node.PROCESS_MODE_DISABLED diff --git a/scenes/mainmenu.tscn b/scenes/mainmenu.tscn index 391b265..eddb97e 100644 --- a/scenes/mainmenu.tscn +++ b/scenes/mainmenu.tscn @@ -116,6 +116,40 @@ theme_override_styles/disabled = SubResource("StyleBoxEmpty_normal") theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_pressed") text = "Play" +[node name="AchievementsButton" type="Button" parent="VBoxContainer" unique_id=444444444] +custom_minimum_size = Vector2(250, 50) +layout_mode = 2 +theme_override_colors/font_color = Color(1, 0.95, 0.8, 1) +theme_override_colors/font_hover_color = Color(1, 1, 0.55, 1) +theme_override_colors/font_pressed_color = Color(1, 1, 0.75, 1) +theme_override_colors/font_focus_color = Color(1, 0.95, 0.8, 1) +theme_override_fonts/font = ExtResource("4_3vvtq") +theme_override_font_sizes/font_size = 32 +theme_override_styles/normal = SubResource("StyleBoxEmpty_normal") +theme_override_styles/hover = SubResource("StyleBoxFlat_hover") +theme_override_styles/pressed = SubResource("StyleBoxFlat_pressed") +theme_override_styles/focus = SubResource("StyleBoxEmpty_focus") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_normal") +theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_pressed") +text = "Achievements" + +[node name="StatsButton" type="Button" parent="VBoxContainer" unique_id=333333333] +custom_minimum_size = Vector2(250, 50) +layout_mode = 2 +theme_override_colors/font_color = Color(1, 0.95, 0.8, 1) +theme_override_colors/font_hover_color = Color(1, 1, 0.55, 1) +theme_override_colors/font_pressed_color = Color(1, 1, 0.75, 1) +theme_override_colors/font_focus_color = Color(1, 0.95, 0.8, 1) +theme_override_fonts/font = ExtResource("4_3vvtq") +theme_override_font_sizes/font_size = 32 +theme_override_styles/normal = SubResource("StyleBoxEmpty_normal") +theme_override_styles/hover = SubResource("StyleBoxFlat_hover") +theme_override_styles/pressed = SubResource("StyleBoxFlat_pressed") +theme_override_styles/focus = SubResource("StyleBoxEmpty_focus") +theme_override_styles/disabled = SubResource("StyleBoxEmpty_normal") +theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_pressed") +text = "Stats" + [node name="OptionsButton" type="Button" parent="VBoxContainer" unique_id=1460263213] custom_minimum_size = Vector2(250, 50) layout_mode = 2 @@ -150,23 +184,6 @@ theme_override_styles/disabled = SubResource("StyleBoxEmpty_normal") theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_pressed") text = "Credits" -[node name="StatsButton" type="Button" parent="VBoxContainer" unique_id=333333333] -custom_minimum_size = Vector2(250, 50) -layout_mode = 2 -theme_override_colors/font_color = Color(1, 0.95, 0.8, 1) -theme_override_colors/font_hover_color = Color(1, 1, 0.55, 1) -theme_override_colors/font_pressed_color = Color(1, 1, 0.75, 1) -theme_override_colors/font_focus_color = Color(1, 0.95, 0.8, 1) -theme_override_fonts/font = ExtResource("4_3vvtq") -theme_override_font_sizes/font_size = 32 -theme_override_styles/normal = SubResource("StyleBoxEmpty_normal") -theme_override_styles/hover = SubResource("StyleBoxFlat_hover") -theme_override_styles/pressed = SubResource("StyleBoxFlat_pressed") -theme_override_styles/focus = SubResource("StyleBoxEmpty_focus") -theme_override_styles/disabled = SubResource("StyleBoxEmpty_normal") -theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_pressed") -text = "Stats" - [node name="QuitButton" type="Button" parent="VBoxContainer" unique_id=1704957427] custom_minimum_size = Vector2(250, 50) layout_mode = 2 @@ -187,5 +204,6 @@ text = "Quit" [connection signal="pressed" from="VBoxContainer/PlayButton" to="." method="_on_play_button_pressed"] [connection signal="pressed" from="VBoxContainer/OptionsButton" to="." method="_on_options_button_pressed"] [connection signal="pressed" from="VBoxContainer/CreditsButton" to="." method="_on_credits_button_pressed"] +[connection signal="pressed" from="VBoxContainer/AchievementsButton" to="." method="_on_achievements_button_pressed"] [connection signal="pressed" from="VBoxContainer/StatsButton" to="." method="_on_stats_button_pressed"] [connection signal="pressed" from="VBoxContainer/QuitButton" to="." method="_on_quit_button_pressed"] diff --git a/scripts/achievement_manager.gd b/scripts/achievement_manager.gd new file mode 100644 index 0000000..42fa77d --- /dev/null +++ b/scripts/achievement_manager.gd @@ -0,0 +1,193 @@ +extends Node + +const SAVE_PATH = "user://achievements.json" +var achievements: Array = [] + +func _ready() -> void: + _define() + _load() + check_all() + +func _define() -> void: + achievements = [ + { + "id": "first_blood", + "title": "First Blood", + "description": "Kill your very first enemy.", + "condition_type": "kills_total", + "threshold": 1, + "reward": "+10 Max HP at the start of every run", + "color": Color(0.55, 0.08, 0.08), + "icon_char": "I", + "unlocked": false + }, + { + "id": "slime_slayer", + "title": "Slime Slayer", + "description": "Kill 25 Blue Slimes.", + "condition_type": "kills_blue_slime", + "threshold": 25, + "reward": "Shurikens pierce 1 additional enemy", + "color": Color(0.15, 0.2, 0.65), + "icon_char": "B", + "unlocked": false + }, + { + "id": "fire_bane", + "title": "Fire Bane", + "description": "Kill 50 Fire Slimes.", + "condition_type": "kills_fire_slime", + "threshold": 50, + "reward": "Fireball permanently deals +20% more damage", + "color": Color(0.75, 0.28, 0.05), + "icon_char": "F", + "unlocked": false + }, + { + "id": "apprentice", + "title": "Apprentice", + "description": "Cast 50 spells in total.", + "condition_type": "spells_total", + "threshold": 50, + "reward": "Cauldron brews with only 2 fruits instead of 3", + "color": Color(0.45, 0.1, 0.7), + "icon_char": "A", + "unlocked": false + }, + { + "id": "slime_hunter", + "title": "Slime Hunter", + "description": "Kill 100 enemies in total.", + "condition_type": "kills_total", + "threshold": 100, + "reward": "Each run starts with 1 random fruit already in the cauldron", + "color": Color(0.15, 0.5, 0.15), + "icon_char": "H", + "unlocked": false + }, + { + "id": "survivor", + "title": "Survivor", + "description": "Survive 3 minutes in a single run.", + "condition_type": "survive_best", + "threshold": 180, + "reward": "Regenerate 5 HP every 10 seconds", + "color": Color(0.1, 0.4, 0.65), + "icon_char": "S", + "unlocked": false + }, + { + "id": "veteran", + "title": "Veteran", + "description": "Play 15 runs.", + "condition_type": "runs_played", + "threshold": 15, + "reward": "Start each run with 1 random perk already applied", + "color": Color(0.6, 0.45, 0.05), + "icon_char": "V", + "unlocked": false + }, + { + "id": "archmage", + "title": "Archmage", + "description": "Cast 300 spells in total.", + "condition_type": "spells_total", + "threshold": 300, + "reward": "All spells permanently deal +15% more damage", + "color": Color(0.25, 0.05, 0.5), + "icon_char": "M", + "unlocked": false + }, + { + "id": "iron_witch", + "title": "Iron Witch", + "description": "Survive 7 minutes in a single run.", + "condition_type": "survive_best", + "threshold": 420, + "reward": "+25 Max HP permanently", + "color": Color(0.25, 0.35, 0.5), + "icon_char": "W", + "unlocked": false + }, + { + "id": "exterminator", + "title": "Exterminator", + "description": "Kill 500 enemies in total.", + "condition_type": "kills_total", + "threshold": 500, + "reward": "Level-up screen shows 4 perk cards instead of 3", + "color": Color(0.65, 0.05, 0.05), + "icon_char": "X", + "unlocked": false + }, + ] + +func check_all() -> void: + var changed = false + for ach in achievements: + if ach.unlocked: + continue + if _meets(ach): + ach.unlocked = true + changed = true + if changed: + _save() + +func _meets(ach: Dictionary) -> bool: + var d = StatsManager.data + var t: int = ach.threshold + match ach.condition_type: + "kills_total": + var total = 0 + for v in d["kills"].values(): + total += v + return total >= t + "kills_blue_slime": + return d["kills"]["blue_slime"] >= t + "kills_fire_slime": + return d["kills"]["fire_slime"] >= t + "spells_total": + var total = 0 + for v in d["spells_cast"].values(): + total += v + return total >= t + "survive_best": + return d["longest_run_seconds"] >= t + "runs_played": + return d["runs_played"] >= t + return false + +func get_unlocked_count() -> int: + var n = 0 + for ach in achievements: + if ach.unlocked: + n += 1 + return n + +func _save() -> void: + var ids: Array = [] + for ach in achievements: + if ach.unlocked: + ids.append(ach.id) + var f = FileAccess.open(SAVE_PATH, FileAccess.WRITE) + if f == null: + return + f.store_string(JSON.stringify(ids)) + f.close() + +func _load() -> void: + if not FileAccess.file_exists(SAVE_PATH): + return + var f = FileAccess.open(SAVE_PATH, FileAccess.READ) + if f == null: + return + var j = JSON.new() + var text = f.get_as_text() + f.close() + if j.parse(text) != OK: + return + var ids = j.get_data() + if typeof(ids) != TYPE_ARRAY: + return + for ach in achievements: + ach.unlocked = ach.id in ids diff --git a/scripts/achievement_manager.gd.uid b/scripts/achievement_manager.gd.uid new file mode 100644 index 0000000..500e9ba --- /dev/null +++ b/scripts/achievement_manager.gd.uid @@ -0,0 +1 @@ +uid://doym1fo4mfdxp diff --git a/scripts/achievements_screen.gd b/scripts/achievements_screen.gd new file mode 100644 index 0000000..384bcc6 --- /dev/null +++ b/scripts/achievements_screen.gd @@ -0,0 +1,89 @@ +extends CanvasLayer + +@onready var _grid: GridContainer = $VBoxContainer/AchievementGrid +@onready var _counter: Label = $VBoxContainer/CounterLabel +@onready var _info_title: Label = $VBoxContainer/InfoPanel/InfoVBox/InfoTitle +@onready var _info_desc: Label = $VBoxContainer/InfoPanel/InfoVBox/InfoDesc +@onready var _info_reward: Label = $VBoxContainer/InfoPanel/InfoVBox/InfoReward + +var _font = preload("res://assets/fonts/slkscre.ttf") +var _frame_tex = preload("res://assets/Tiny RPG Mana Soul GUI v1.0/20250420manaSoul9SlicesA-Sheet.png") + +func _ready() -> void: + AchievementManager.check_all() + _update_counter() + _build_grid() + _clear_info() + +func _build_grid() -> void: + for ach in AchievementManager.achievements: + _grid.add_child(_make_slot(ach)) + +func _make_slot(ach: Dictionary) -> Control: + var slot := Control.new() + slot.custom_minimum_size = Vector2(80, 80) + slot.mouse_filter = Control.MOUSE_FILTER_STOP + + var bg := ColorRect.new() + bg.mouse_filter = Control.MOUSE_FILTER_IGNORE + bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + bg.color = ach.color if ach.unlocked else Color(0.06, 0.06, 0.1, 1.0) + slot.add_child(bg) + + var frame := NinePatchRect.new() + frame.mouse_filter = Control.MOUSE_FILTER_IGNORE + frame.texture = _frame_tex + frame.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + frame.patch_margin_left = 8 + frame.patch_margin_right = 8 + frame.patch_margin_top = 8 + frame.patch_margin_bottom = 8 + if not ach.unlocked: + frame.modulate = Color(0.4, 0.4, 0.4, 1.0) + slot.add_child(frame) + + var lbl := Label.new() + lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE + lbl.text = ach.icon_char + lbl.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + lbl.vertical_alignment = VERTICAL_ALIGNMENT_CENTER + lbl.add_theme_font_override("font", _font) + lbl.add_theme_font_size_override("font_size", 26) + if ach.unlocked: + lbl.add_theme_color_override("font_color", Color(1.0, 1.0, 0.9, 1.0)) + lbl.add_theme_color_override("font_outline_color", Color(0.0, 0.0, 0.0, 0.9)) + lbl.add_theme_constant_override("outline_size", 2) + else: + lbl.add_theme_color_override("font_color", Color(0.22, 0.22, 0.22, 1.0)) + slot.add_child(lbl) + + slot.mouse_entered.connect(_on_slot_enter.bind(ach)) + slot.mouse_exited.connect(_on_slot_exit) + return slot + +func _on_slot_enter(ach: Dictionary) -> void: + if ach.unlocked: + _info_title.text = ach.title + " [UNLOCKED]" + _info_title.add_theme_color_override("font_color", Color(1.0, 1.0, 0.55, 1.0)) + else: + _info_title.text = ach.title + " [LOCKED]" + _info_title.add_theme_color_override("font_color", Color(0.75, 0.45, 1.0, 1.0)) + _info_desc.text = ach.description + _info_reward.text = "Reward: " + ach.reward + +func _on_slot_exit() -> void: + _clear_info() + +func _clear_info() -> void: + _info_title.text = "" + _info_desc.text = "Hover over an achievement to see details." + _info_reward.text = "" + +func _update_counter() -> void: + var n := AchievementManager.get_unlocked_count() + var total := AchievementManager.achievements.size() + _counter.text = "Unlocked: %d of %d" % [n, total] + +func _on_back_button_pressed() -> void: + get_tree().change_scene_to_file("res://scenes/mainmenu.tscn") diff --git a/scripts/achievements_screen.gd.uid b/scripts/achievements_screen.gd.uid new file mode 100644 index 0000000..4846b32 --- /dev/null +++ b/scripts/achievements_screen.gd.uid @@ -0,0 +1 @@ +uid://yv14n6gesnt5 diff --git a/scripts/mainmenu.gd b/scripts/mainmenu.gd index 449c933..051231a 100644 --- a/scripts/mainmenu.gd +++ b/scripts/mainmenu.gd @@ -12,6 +12,9 @@ func _on_options_button_pressed() -> void: func _on_credits_button_pressed() -> void: get_tree().change_scene_to_file("res://scenes/credits.tscn") +func _on_achievements_button_pressed() -> void: + get_tree().change_scene_to_file("res://scenes/achievements_screen.tscn") + func _on_stats_button_pressed() -> void: get_tree().change_scene_to_file("res://scenes/stats_screen.tscn") diff --git a/scripts/pause_menu.gd b/scripts/pause_menu.gd index 5c6ccc5..c4f81d9 100644 --- a/scripts/pause_menu.gd +++ b/scripts/pause_menu.gd @@ -19,6 +19,7 @@ func _on_continue_button_pressed() -> void: func _on_quit_button_pressed() -> void: StatsManager.end_run(false) + AchievementManager.check_all() get_tree().quit()