244 lines
7.7 KiB
GDScript
244 lines
7.7 KiB
GDScript
extends Control
|
|
|
|
static var volume: float = 100.0
|
|
|
|
var settings_panel: Panel
|
|
var difficulty_panel: Panel
|
|
|
|
func _ready() -> void:
|
|
process_mode = Node.PROCESS_MODE_ALWAYS
|
|
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
_build_ui()
|
|
_apply_volume(volume)
|
|
|
|
func _build_ui() -> void:
|
|
var bg := ColorRect.new()
|
|
bg.color = Color(0.06, 0.04, 0.10)
|
|
bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
add_child(bg)
|
|
|
|
var title := Label.new()
|
|
title.text = "KickSurvivors"
|
|
title.add_theme_font_size_override("font_size", 52)
|
|
title.add_theme_color_override("font_color", Color.WHITE)
|
|
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
title.anchor_left = 0.5
|
|
title.anchor_right = 0.5
|
|
title.anchor_top = 0.0
|
|
title.offset_left = -200
|
|
title.offset_right = 200
|
|
title.offset_top = 110
|
|
add_child(title)
|
|
|
|
var vbox := VBoxContainer.new()
|
|
vbox.add_theme_constant_override("separation", 14)
|
|
vbox.anchor_left = 0.5
|
|
vbox.anchor_right = 0.5
|
|
vbox.anchor_top = 0.5
|
|
vbox.anchor_bottom = 0.5
|
|
vbox.offset_left = -110
|
|
vbox.offset_right = 110
|
|
vbox.offset_top = -90
|
|
vbox.offset_bottom = 90
|
|
add_child(vbox)
|
|
|
|
vbox.add_child(_btn("Играть", _on_play))
|
|
vbox.add_child(_btn("Настройки", _on_settings))
|
|
vbox.add_child(_btn("Выход", _on_exit))
|
|
|
|
_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
|
|
b.custom_minimum_size = Vector2(220, 54)
|
|
b.add_theme_font_size_override("font_size", 20)
|
|
for state in ["normal", "hover", "pressed", "focus", "disabled"]:
|
|
var sb := StyleBoxFlat.new()
|
|
sb.bg_color = Color(0.18, 0.13, 0.30) if state == "normal" else (
|
|
Color(0.28, 0.20, 0.46) if state == "hover" else
|
|
Color(0.12, 0.09, 0.22))
|
|
sb.border_width_left = 1
|
|
sb.border_width_right = 1
|
|
sb.border_width_top = 1
|
|
sb.border_width_bottom = 1
|
|
sb.border_color = Color(0.50, 0.38, 0.75)
|
|
sb.corner_radius_top_left = 6
|
|
sb.corner_radius_top_right = 6
|
|
sb.corner_radius_bottom_left = 6
|
|
sb.corner_radius_bottom_right = 6
|
|
sb.content_margin_left = 20
|
|
sb.content_margin_right = 20
|
|
sb.content_margin_top = 12
|
|
sb.content_margin_bottom = 12
|
|
b.add_theme_stylebox_override(state, sb)
|
|
b.connect("pressed", cb)
|
|
return b
|
|
|
|
static func _make_opaque_panel() -> Panel:
|
|
var p := Panel.new()
|
|
var sb := StyleBoxFlat.new()
|
|
sb.bg_color = Color(0.08, 0.06, 0.14)
|
|
sb.border_width_left = 2
|
|
sb.border_width_right = 2
|
|
sb.border_width_top = 2
|
|
sb.border_width_bottom = 2
|
|
sb.border_color = Color(0.35, 0.28, 0.55)
|
|
sb.corner_radius_top_left = 8
|
|
sb.corner_radius_top_right = 8
|
|
sb.corner_radius_bottom_left = 8
|
|
sb.corner_radius_bottom_right = 8
|
|
sb.content_margin_left = 24
|
|
sb.content_margin_right = 24
|
|
sb.content_margin_top = 20
|
|
sb.content_margin_bottom = 20
|
|
p.add_theme_stylebox_override("panel", sb)
|
|
return p
|
|
|
|
func _build_settings_panel() -> void:
|
|
settings_panel = _make_opaque_panel()
|
|
settings_panel.visible = false
|
|
settings_panel.anchor_left = 0.5
|
|
settings_panel.anchor_right = 0.5
|
|
settings_panel.anchor_top = 0.5
|
|
settings_panel.anchor_bottom = 0.5
|
|
settings_panel.offset_left = -200
|
|
settings_panel.offset_right = 200
|
|
settings_panel.offset_top = -130
|
|
settings_panel.offset_bottom = 130
|
|
add_child(settings_panel)
|
|
|
|
var vbox := VBoxContainer.new()
|
|
vbox.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
vbox.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
vbox.add_theme_constant_override("separation", 18)
|
|
settings_panel.add_child(vbox)
|
|
|
|
var lbl := Label.new()
|
|
lbl.text = "Настройки"
|
|
lbl.add_theme_font_size_override("font_size", 26)
|
|
lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
vbox.add_child(lbl)
|
|
|
|
var vol_lbl := Label.new()
|
|
vol_lbl.name = "VolumeLabel"
|
|
vol_lbl.text = "Громкость: %d" % int(volume)
|
|
vol_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
vbox.add_child(vol_lbl)
|
|
|
|
var slider := HSlider.new()
|
|
slider.min_value = 0
|
|
slider.max_value = 100
|
|
slider.step = 1
|
|
slider.value = volume
|
|
slider.custom_minimum_size = Vector2(320, 32)
|
|
slider.connect("value_changed", func(v: float) -> void:
|
|
volume = v
|
|
vol_lbl.text = "Громкость: %d" % int(v)
|
|
_apply_volume(v)
|
|
)
|
|
vbox.add_child(slider)
|
|
|
|
vbox.add_child(_btn("Назад", func(): settings_panel.visible = false))
|
|
|
|
func _apply_volume(v: float) -> void:
|
|
var db := linear_to_db(v / 100.0) if v > 0.0 else -80.0
|
|
AudioServer.set_bus_volume_db(0, db)
|
|
|
|
func _build_difficulty_panel() -> void:
|
|
difficulty_panel = _make_opaque_panel()
|
|
difficulty_panel.visible = false
|
|
difficulty_panel.anchor_left = 0.5
|
|
difficulty_panel.anchor_right = 0.5
|
|
difficulty_panel.anchor_top = 0.5
|
|
difficulty_panel.anchor_bottom = 0.5
|
|
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()
|
|
margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
margin.add_theme_constant_override("margin_left", 24)
|
|
margin.add_theme_constant_override("margin_right", 24)
|
|
margin.add_theme_constant_override("margin_top", 20)
|
|
margin.add_theme_constant_override("margin_bottom", 20)
|
|
difficulty_panel.add_child(margin)
|
|
|
|
var vbox := VBoxContainer.new()
|
|
vbox.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
vbox.add_theme_constant_override("separation", 16)
|
|
margin.add_child(vbox)
|
|
|
|
var title := Label.new()
|
|
title.text = "Выберите сложность"
|
|
title.add_theme_font_size_override("font_size", 26)
|
|
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
vbox.add_child(title)
|
|
|
|
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(_big_btn("Выживание\nПолучаешь урон · фиксированная сила пинка", 540, func() -> void:
|
|
GameSettings.difficulty = "survival"
|
|
get_tree().change_scene_to_file("res://scenes/Main.tscn")
|
|
))
|
|
|
|
# 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 := [
|
|
["Медленно", 10.0, 15.0],
|
|
["Нормально", 8.0, 15.0],
|
|
["Быстро", 6.0, 10.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))
|
|
|
|
func _on_play() -> void:
|
|
difficulty_panel.visible = true
|
|
|
|
func _on_settings() -> void:
|
|
settings_panel.visible = true
|
|
|
|
func _on_exit() -> void:
|
|
get_tree().quit()
|