From 3c2afefc95caf9a908d23a38dfbff10ec521ef5d Mon Sep 17 00:00:00 2001 From: Nikolai Fedorov Date: Thu, 23 Apr 2026 16:17:40 +0300 Subject: [PATCH] spawn settings --- scripts/GameSettings.gd | 6 ++++ scripts/Main.gd | 8 ++--- scripts/MainMenu.gd | 69 ++++++++++++++++++++++++++++++----------- 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/scripts/GameSettings.gd b/scripts/GameSettings.gd index 7cdbd57..da6d3a9 100644 --- a/scripts/GameSettings.gd +++ b/scripts/GameSettings.gd @@ -3,3 +3,9 @@ class_name GameSettings ## "immortal" — no damage, tier-based kick force ## "survival" — takes damage, fixed kick force static var difficulty: String = "immortal" + +## enemy spawn interval in seconds +static var enemy_spawn_interval: float = 10.0 + +## item (rock/stick) respawn delay in seconds +static var item_respawn_delay: float = 20.0 diff --git a/scripts/Main.gd b/scripts/Main.gd index 52da3d3..1080478 100644 --- a/scripts/Main.gd +++ b/scripts/Main.gd @@ -177,7 +177,7 @@ func _on_stick_destroyed() -> void: return if sticks_on_field + sticks_pending < STICK_LIMIT: sticks_pending += 1 - await get_tree().create_timer(20.0).timeout + await get_tree().create_timer(GameSettings.item_respawn_delay).timeout sticks_pending -= 1 if game_active: _spawn_single_stick() @@ -213,7 +213,7 @@ func _on_rock_destroyed() -> void: return if rocks_on_field + rocks_pending < _get_rock_limit(): rocks_pending += 1 - await get_tree().create_timer(20.0).timeout + await get_tree().create_timer(GameSettings.item_respawn_delay).timeout rocks_pending -= 1 if game_active: _spawn_single_rock() @@ -244,7 +244,7 @@ func _start_game() -> void: Enemy.first_iron_spawned = false Enemy.first_essence_spawned = false _update_labels() - spawn_timer.wait_time = 1.4 + spawn_timer.wait_time = GameSettings.enemy_spawn_interval spawn_timer.connect("timeout", _on_spawn_timer) spawn_timer.start() @@ -252,7 +252,7 @@ func _on_spawn_timer() -> void: if not game_active or upgrading: return _spawn_enemy() - spawn_timer.wait_time = SPAWN_TIME # max(0.25, 1.4 - wave * 0.07) + spawn_timer.wait_time = GameSettings.enemy_spawn_interval func _spawn_enemy() -> void: var enemy := ENEMY_SCENE.instantiate() as CharacterBody3D diff --git a/scripts/MainMenu.gd b/scripts/MainMenu.gd index 56a450b..5bb3fac 100644 --- a/scripts/MainMenu.gd +++ b/scripts/MainMenu.gd @@ -49,6 +49,12 @@ func _build_ui() -> void: _build_settings_panel() _build_difficulty_panel() +func _big_btn(text: String, width: float, cb: Callable) -> Button: + var b := _btn(text, cb) + b.custom_minimum_size = Vector2(width, 72) + b.add_theme_font_size_override("font_size", 18) + return b + func _btn(text: String, cb: Callable) -> Button: var b := Button.new() b.text = text @@ -153,10 +159,10 @@ func _build_difficulty_panel() -> void: difficulty_panel.anchor_right = 0.5 difficulty_panel.anchor_top = 0.5 difficulty_panel.anchor_bottom = 0.5 - difficulty_panel.offset_left = -230 - difficulty_panel.offset_right = 230 - difficulty_panel.offset_top = -160 - difficulty_panel.offset_bottom = 160 + difficulty_panel.offset_left = -310 + difficulty_panel.offset_right = 310 + difficulty_panel.offset_top = -240 + difficulty_panel.offset_bottom = 240 add_child(difficulty_panel) var margin := MarginContainer.new() @@ -178,25 +184,52 @@ func _build_difficulty_panel() -> void: title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER vbox.add_child(title) - var immortal_btn := Button.new() - immortal_btn.text = "Бессмертный\nНет урона · тир пинков от мелких врагов" - immortal_btn.custom_minimum_size = Vector2(380, 72) - immortal_btn.add_theme_font_size_override("font_size", 18) - immortal_btn.connect("pressed", func() -> void: + vbox.add_child(_big_btn("Бессмертный\nНет урона · тир пинков от мелких врагов", 540, func() -> void: GameSettings.difficulty = "immortal" get_tree().change_scene_to_file("res://scenes/Main.tscn") - ) - vbox.add_child(immortal_btn) + )) - var survival_btn := Button.new() - survival_btn.text = "Выживание\nПолучаешь урон · фиксированная сила пинка" - survival_btn.custom_minimum_size = Vector2(380, 72) - survival_btn.add_theme_font_size_override("font_size", 18) - survival_btn.connect("pressed", func() -> void: + vbox.add_child(_big_btn("Выживание\nПолучаешь урон · фиксированная сила пинка", 540, func() -> void: GameSettings.difficulty = "survival" get_tree().change_scene_to_file("res://scenes/Main.tscn") - ) - vbox.add_child(survival_btn) + )) + + # Spawn speed row + var spawn_lbl := Label.new() + spawn_lbl.text = "Скорость спавна:" + spawn_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + spawn_lbl.add_theme_font_size_override("font_size", 16) + spawn_lbl.add_theme_color_override("font_color", Color(0.85, 0.78, 1.0)) + vbox.add_child(spawn_lbl) + + var hbox := HBoxContainer.new() + hbox.alignment = BoxContainer.ALIGNMENT_CENTER + hbox.add_theme_constant_override("separation", 10) + vbox.add_child(hbox) + + var spawn_options := [ + ["Медленно", 15.0, 35.0], + ["Нормально", 10.0, 20.0], + ["Быстро", 5.0, 8.0], + ] + var spawn_btns: Array[Button] = [] + for opt in spawn_options: + var sb_btn := _btn(opt[0] as String, Callable()) + sb_btn.custom_minimum_size = Vector2(110, 40) + sb_btn.add_theme_font_size_override("font_size", 15) + var enemy_iv: float = opt[1] + var item_iv: float = opt[2] + sb_btn.connect("pressed", func() -> void: + GameSettings.enemy_spawn_interval = enemy_iv + GameSettings.item_respawn_delay = item_iv + for b in spawn_btns: + b.modulate = Color(1, 1, 1) + sb_btn.modulate = Color(0.7, 1.0, 0.5) + ) + hbox.add_child(sb_btn) + spawn_btns.append(sb_btn) + # default: normal + spawn_btns[1].modulate = Color(0.7, 1.0, 0.5) vbox.add_child(_btn("Назад", func(): difficulty_panel.visible = false))