Added level selection screen

This commit is contained in:
2026-01-08 21:24:10 +03:00
parent 7e55578994
commit bc0c494244
16 changed files with 186 additions and 15 deletions
+21 -10
View File
@@ -2,28 +2,39 @@ class_name CompletionMenu
extends Control
@export var next_level : PackedScene
@onready var next_level_button : Button = $%NextLevelButton
@onready var main_menu_button : Button = $%MainMenuButton
@onready var focus_timer : Timer = $FocusTimer
func _get_next_level(remove := false) -> PackedScene:
var next_level : PackedScene = get_tree().get_meta(AbstractLevel.NEXT_LEVEL_META, null)
if remove:
get_tree().remove_meta(AbstractLevel.NEXT_LEVEL_META)
return next_level
func _on_next_level_button_pressed() -> void:
get_tree().paused = false
if next_level != null:
get_tree().change_scene_to_packed(next_level)
else:
get_tree().change_scene_to_file("res://game/menu/main_menu.tscn")
get_tree().change_scene_to_packed(_get_next_level(true))
func _on_main_menu_button_pressed() -> void:
get_tree().paused = false
get_tree().change_scene_to_file("res://game/menu/main_menu.tscn")
func _on_visibility_changed() -> void:
if visible:
next_level_button.visible = _get_next_level() != null
if focus_timer != null:
focus_timer.start()
func _on_focus_timer_timeout() -> void:
if next_level_button != null:
next_level_button.grab_focus()
if next_level_button != null and next_level_button.visible:
next_level_button.grab_focus()
elif main_menu_button != null:
main_menu_button.grab_focus()
+6
View File
@@ -48,9 +48,15 @@ unique_name_in_owner = true
layout_mode = 2
text = "Next level"
[node name="MainMenuButton" type="Button" parent="MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Main menu"
[node name="FocusTimer" type="Timer" parent="."]
one_shot = true
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/NextLevelButton" to="." method="_on_next_level_button_pressed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/MainMenuButton" to="." method="_on_main_menu_button_pressed"]
[connection signal="timeout" from="FocusTimer" to="." method="_on_focus_timer_timeout"]
+7 -1
View File
@@ -2,10 +2,16 @@ class_name GameOverMenu
extends Control
@onready var retry_button : Button = $%RetryButton
@onready var main_menu_button : Button = $%MainMenuButton
@onready var focus_timer : Timer = $FocusTimer
func _on_retry_button_pressed() -> void:
get_tree().paused = false
get_tree().change_scene_to_file(get_tree().current_scene.scene_file_path)
func _on_main_menu_button_pressed() -> void:
get_tree().paused = false
get_tree().change_scene_to_file("res://game/menu/main_menu.tscn")
@@ -19,4 +25,4 @@ func _on_visibility_changed() -> void:
func _on_focus_timer_timeout() -> void:
if main_menu_button != null:
main_menu_button.grab_focus()
retry_button.grab_focus()
+6
View File
@@ -43,6 +43,11 @@ layout_mode = 2
text = "Game over!"
horizontal_alignment = 1
[node name="RetryButton" type="Button" parent="MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Retry"
[node name="MainMenuButton" type="Button" parent="MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
@@ -52,5 +57,6 @@ text = "Main menu"
one_shot = true
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/RetryButton" to="." method="_on_retry_button_pressed"]
[connection signal="pressed" from="MarginContainer/VBoxContainer/MainMenuButton" to="." method="_on_main_menu_button_pressed"]
[connection signal="timeout" from="FocusTimer" to="." method="_on_focus_timer_timeout"]
+37
View File
@@ -0,0 +1,37 @@
class_name LevelSelection
extends Control
@export var levels : Array[PackedScene] = []
@onready var grid : GridContainer = $%GridContainer
func _ready() -> void:
levels = levels.filter(func(item: PackedScene) -> bool: return item != null)
for i in range(levels.size()):
var level := levels[i]
var next_level := levels[i+1] if i+1 < levels.size() else null
var disable := SaveManager.completed_levels < i
var button : Button = Button.new()
button.text = "Level %d" % (i + 1)
button.disabled = disable
button.focus_mode = Control.FOCUS_NONE if disable else Control.FOCUS_ALL
grid.add_child(button)
button.pressed.connect(_on_level_selected.bind(i, level, next_level))
if i == 0:
button.grab_focus()
func _on_level_selected(index: int, level: PackedScene, next_level: PackedScene) -> void:
get_tree().set_meta(AbstractLevel.CURRENT_LEVEL_INDEX, index)
get_tree().set_meta(AbstractLevel.NEXT_LEVEL_META, next_level)
get_tree().change_scene_to_packed(level)
func _on_main_menu_button_pressed() -> void:
get_tree().change_scene_to_file("res://game/menu/main_menu.tscn")
+1
View File
@@ -0,0 +1 @@
uid://47impoi24o7g
+45
View File
@@ -0,0 +1,45 @@
[gd_scene load_steps=4 format=3 uid="uid://cdw72hewwmypn"]
[ext_resource type="Theme" uid="uid://bh56my8b2htnr" path="res://themes/menu.tres" id="1_5cn0b"]
[ext_resource type="Script" uid="uid://47impoi24o7g" path="res://game/menu/level_selection.gd" id="1_fb5q3"]
[ext_resource type="PackedScene" uid="uid://bmn74wc2vophn" path="res://game/levels/test_level.tscn" id="3_3oqjo"]
[node name="LevelSelection" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_5cn0b")
script = ExtResource("1_fb5q3")
levels = Array[PackedScene]([ExtResource("3_3oqjo"), ExtResource("3_3oqjo")])
[node name="MarginContainer" type="MarginContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"]
layout_mode = 2
alignment = 1
[node name="GridContainer" type="GridContainer" parent="MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 6
columns = 4
[node name="Control" type="Control" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="MainMenuButton" type="Button" parent="MarginContainer/VBoxContainer"]
layout_mode = 2
text = "Main menu"
[connection signal="pressed" from="MarginContainer/VBoxContainer/MainMenuButton" to="." method="_on_main_menu_button_pressed"]
+1 -1
View File
@@ -22,7 +22,7 @@ func _setup_neighbors() -> void:
func _on_start_button_pressed() -> void:
get_tree().change_scene_to_file("res://game/levels/level_1.tscn")
get_tree().change_scene_to_file("res://game/menu/level_selection.tscn")
func _on_options_button_pressed() -> void: