From 5b8c59d67f780c693e5e95eef826f2a50dbc018d Mon Sep 17 00:00:00 2001 From: Ruslan Ignatov Date: Mon, 15 Dec 2025 17:10:25 +0300 Subject: [PATCH] Added seed selection screen --- game/game_data.gd | 12 ++--- managers/save_manager.gd | 6 ++- menu/seed_selection_menu.gd | 96 +++++++++++++++++++++++++++++++++ menu/seed_selection_menu.gd.uid | 1 + menu/seed_selection_menu.tscn | 73 +++++++++++++++++++++++++ menu/title_screen.gd | 17 +++--- menu/title_screen.tscn | 19 ++++++- project.godot | 1 - 8 files changed, 201 insertions(+), 24 deletions(-) create mode 100644 menu/seed_selection_menu.gd create mode 100644 menu/seed_selection_menu.gd.uid create mode 100644 menu/seed_selection_menu.tscn diff --git a/game/game_data.gd b/game/game_data.gd index 8975d28..7bd1a11 100644 --- a/game/game_data.gd +++ b/game/game_data.gd @@ -1,8 +1,7 @@ class_name GameData extends Resource -const SEED_CHARS := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -const DEFAULT_SEED_LENGTH := 16 + @export var game_seed: String @@ -11,13 +10,8 @@ const DEFAULT_SEED_LENGTH := 16 @export var current_sector_index: int -func randomize() -> void: - var seed_chars_length := SEED_CHARS.length() - - for i in range(DEFAULT_SEED_LENGTH): - var index := randi_range(1, seed_chars_length) - 1 - game_seed += SEED_CHARS[index] - +func reset() -> void: + game_seed = "" current_area_index = 0 current_stage_index = 0 current_sector_index = 0 diff --git a/managers/save_manager.gd b/managers/save_manager.gd index a32742a..3bd3ae5 100644 --- a/managers/save_manager.gd +++ b/managers/save_manager.gd @@ -36,8 +36,10 @@ func save() -> void: _save_file.save_encrypted_pass(SAVE_FILE, SAVE_FILE_PASS) -func new_game() -> void: - game_data.randomize() +func new_game(game_seed: String) -> void: + game_data.reset() + player_data.reset() + game_data.game_seed = game_seed func delete_game_data() -> void: diff --git a/menu/seed_selection_menu.gd b/menu/seed_selection_menu.gd new file mode 100644 index 0000000..18ff911 --- /dev/null +++ b/menu/seed_selection_menu.gd @@ -0,0 +1,96 @@ +class_name SeedSelectionMenu +extends Control + + +signal back + + +const SEED_CHARS := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +const DEFAULT_SEED_LENGTH := 16 + + +var _seed_regex := RegEx.new() +var _random_seed := "" + + +@onready var seed_label : Label = $%SeedLabel +@onready var seed_edit : LineEdit = $%SeedEdit + +@onready var use_random_button : Button = $%UseRandomButton +@onready var use_custom_button : Button = $%UseCustomButton + + +func _init() -> void: + var regex_pattern := "[%s]+" % SEED_CHARS + _seed_regex.compile(regex_pattern) + + +func _update_use_custom_button() -> void: + var disabled := seed_edit.text.is_empty() + use_custom_button.disabled = disabled + use_custom_button.focus_mode = FOCUS_NONE if disabled else FOCUS_ALL + + +func _init_focus() -> void: + _update_use_custom_button() + use_random_button.grab_focus() + + +func _get_random_seed() -> String: + var seed_chars_length := SEED_CHARS.length() + + var random_seed := "" + for i in range(DEFAULT_SEED_LENGTH): + var index := randi_range(1, seed_chars_length) - 1 + random_seed += SEED_CHARS[index] + + return random_seed + + +func _start_game(game_seed: String) -> void: + SaveManager.new_game(game_seed) + get_tree().change_scene_to_file("res://game/game.tscn") + + +func _on_seed_edit_text_changed(new_text: String) -> void: + var result := _seed_regex.search_all(new_text) + + var filtered_text := "" + for text in result: + filtered_text += text.get_string() + + if seed_edit.text != filtered_text: + var caret_position := seed_edit.caret_column + seed_edit.text = filtered_text + seed_edit.caret_column = min(caret_position, filtered_text.length()) + + _update_use_custom_button() + + +func _on_seed_edit_text_submitted(new_text: String) -> void: + if not new_text.is_empty(): + use_custom_button.grab_focus() + + +func _on_back_button_pressed() -> void: + back.emit() + + +func _on_visibility_changed() -> void: + if not is_node_ready(): return + if not visible: return + + _random_seed = _get_random_seed() + + seed_edit.text = "" + seed_label.text = _random_seed + + _init_focus() + + +func _on_use_random_button_pressed() -> void: + _start_game(_random_seed) + + +func _on_use_custom_button_pressed() -> void: + _start_game(seed_edit.text) diff --git a/menu/seed_selection_menu.gd.uid b/menu/seed_selection_menu.gd.uid new file mode 100644 index 0000000..94eece4 --- /dev/null +++ b/menu/seed_selection_menu.gd.uid @@ -0,0 +1 @@ +uid://dyynshvsgnepp diff --git a/menu/seed_selection_menu.tscn b/menu/seed_selection_menu.tscn new file mode 100644 index 0000000..1f03806 --- /dev/null +++ b/menu/seed_selection_menu.tscn @@ -0,0 +1,73 @@ +[gd_scene load_steps=3 format=3 uid="uid://c36n317rhv8k7"] + +[ext_resource type="Script" uid="uid://dyynshvsgnepp" path="res://menu/seed_selection_menu.gd" id="1_g2smo"] +[ext_resource type="Theme" uid="uid://dtnd3tqllufey" path="res://images/menu_button.tres" id="2_s4s14"] + +[node name="SeedSelection" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_g2smo") + +[node name="GridContainer" type="GridContainer" parent="."] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -107.5 +offset_top = -33.0 +offset_right = 107.5 +offset_bottom = 33.0 +grow_horizontal = 2 +grow_vertical = 2 +columns = 2 + +[node name="SeedLabel" type="Label" parent="GridContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 +horizontal_alignment = 1 + +[node name="UseRandomButton" type="Button" parent="GridContainer"] +unique_name_in_owner = true +layout_mode = 2 +mouse_filter = 2 +theme = ExtResource("2_s4s14") +text = "Use random seed" + +[node name="SeedEdit" type="LineEdit" parent="GridContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 +mouse_filter = 2 +placeholder_text = "Enter seed" +alignment = 1 +max_length = 16 + +[node name="UseCustomButton" type="Button" parent="GridContainer"] +unique_name_in_owner = true +layout_mode = 2 +mouse_filter = 2 +theme = ExtResource("2_s4s14") +text = "Use custom seed" + +[node name="Label" type="Label" parent="GridContainer"] +layout_mode = 2 + +[node name="BackButton" type="Button" parent="GridContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme = ExtResource("2_s4s14") +text = "Main menu" + +[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"] +[connection signal="pressed" from="GridContainer/UseRandomButton" to="." method="_on_use_random_button_pressed"] +[connection signal="text_changed" from="GridContainer/SeedEdit" to="." method="_on_seed_edit_text_changed"] +[connection signal="text_submitted" from="GridContainer/SeedEdit" to="." method="_on_seed_edit_text_submitted"] +[connection signal="pressed" from="GridContainer/UseCustomButton" to="." method="_on_use_custom_button_pressed"] +[connection signal="pressed" from="GridContainer/BackButton" to="." method="_on_back_button_pressed"] diff --git a/menu/title_screen.gd b/menu/title_screen.gd index 724ac26..c535b5e 100644 --- a/menu/title_screen.gd +++ b/menu/title_screen.gd @@ -4,6 +4,7 @@ extends Control @onready var main_menu : Control = $MainMenu @onready var options : Control = $Options @onready var credits : Control = $Credits +@onready var seed_selection : Control = $SeedSelection func _ready() -> void: @@ -12,7 +13,7 @@ func _ready() -> void: func _show_menu(menu: Control) -> void: - var menus : Array[Control] = [ main_menu, options, credits ] + var menus : Array[Control] = [ main_menu, options, credits, seed_selection ] for m in menus: m.hide() @@ -25,11 +26,7 @@ func _on_main_menu_continue_game() -> void: func _on_main_menu_new_game() -> void: - SaveManager.new_game() - - SaveManager.player_data.reset() - - get_tree().change_scene_to_file("res://game/game.tscn") + _show_menu(seed_selection) func _get_random_weapon_id() -> String: @@ -48,9 +45,9 @@ func _on_options_show_credits() -> void: _show_menu(credits) -func _on_options_back() -> void: - _show_menu(main_menu) - - func _on_credits_back() -> void: _show_menu(options) + + +func _show_main_menu() -> void: + _show_menu(main_menu) diff --git a/menu/title_screen.tscn b/menu/title_screen.tscn index ca51298..092e495 100644 --- a/menu/title_screen.tscn +++ b/menu/title_screen.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=6 format=3 uid="uid://2oavbr7oaihg"] +[gd_scene load_steps=7 format=3 uid="uid://2oavbr7oaihg"] [ext_resource type="Script" uid="uid://bqnepsuk13qo8" path="res://menu/title_screen.gd" id="1_lxdol"] [ext_resource type="PackedScene" uid="uid://bxlccevt52y70" path="res://menu/main_menu.tscn" id="2_o0rbc"] [ext_resource type="PackedScene" uid="uid://btr60idiit4y7" path="res://menu/options.tscn" id="3_88gnj"] [ext_resource type="PackedScene" uid="uid://c3q3g2647qc27" path="res://menu/credits.tscn" id="4_w1y3c"] [ext_resource type="PackedScene" uid="uid://chdrjc7c6bdpb" path="res://game/background.tscn" id="5_88gnj"] +[ext_resource type="PackedScene" uid="uid://c36n317rhv8k7" path="res://menu/seed_selection_menu.tscn" id="5_w1y3c"] [node name="TitleScreen" type="Control"] layout_mode = 3 @@ -20,12 +21,26 @@ layout_mode = 0 [node name="Credits" parent="." instance=ExtResource("4_w1y3c")] layout_mode = 0 +[node name="SeedSelection" parent="." instance=ExtResource("5_w1y3c")] +layout_mode = 0 +anchors_preset = 0 +anchor_right = 0.0 +anchor_bottom = 0.0 +offset_left = 320.0 +offset_top = 190.0 +offset_right = 320.0 +offset_bottom = 190.0 +grow_horizontal = 1 +grow_vertical = 1 +size_flags_horizontal = 4 + [node name="Background" parent="." instance=ExtResource("5_88gnj")] [connection signal="continue_game" from="MainMenu" to="." method="_on_main_menu_continue_game"] [connection signal="new_game" from="MainMenu" to="." method="_on_main_menu_new_game"] [connection signal="quit_game" from="MainMenu" to="." method="_on_main_menu_quit_game"] [connection signal="show_options" from="MainMenu" to="." method="_on_main_menu_show_options"] -[connection signal="back" from="Options" to="." method="_on_options_back"] +[connection signal="back" from="Options" to="." method="_show_main_menu"] [connection signal="show_credits" from="Options" to="." method="_on_options_show_credits"] [connection signal="back" from="Credits" to="." method="_on_credits_back"] +[connection signal="back" from="SeedSelection" to="." method="_show_main_menu"] diff --git a/project.godot b/project.godot index c03fcfe..7df4e3d 100644 --- a/project.godot +++ b/project.godot @@ -54,7 +54,6 @@ ui_accept={ ui_cancel={ "deadzone": 0.5, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194305,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194308,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null) ] }