JuggleBoard game v0.1: Godot 4.7 arcade, combo decay, config menu, circus BGM

This commit is contained in:
enne2
2026-08-10 18:38:45 +02:00
commit 7a2a00aa21
21 changed files with 1133 additions and 0 deletions
+171
View File
@@ -0,0 +1,171 @@
extends CanvasLayer
## Menù di configurazione in-game: slider/spinbox per calibrare velocità e
## moltiplicatori. "Salva e riavvia" persiste le impostazioni e ricarica la
## scena applicando i nuovi valori.
var rows := {} # key -> {slider, spin}
var curve_option: OptionButton
func _ready() -> void:
# Critico: il menù deve ricevere input anche quando il gioco è in pausa,
# altrimenti slider/spinbox/pulsanti risultano congelati e inutilizzabili.
process_mode = Node.PROCESS_MODE_ALWAYS
visible = false
_build()
func _build() -> void:
# sfondo scuro che blocca i click sottostanti
var dim := ColorRect.new()
dim.color = Color(0, 0, 0, 0.65)
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
dim.mouse_filter = Control.MOUSE_FILTER_STOP
add_child(dim)
# pannello centrato
var center := CenterContainer.new()
center.set_anchors_preset(Control.PRESET_FULL_RECT)
add_child(center)
var panel := PanelContainer.new()
center.add_child(panel)
var margin := MarginContainer.new()
margin.add_theme_constant_override("margin_left", 24)
margin.add_theme_constant_override("margin_right", 24)
margin.add_theme_constant_override("margin_top", 16)
margin.add_theme_constant_override("margin_bottom", 16)
panel.add_child(margin)
var vb := VBoxContainer.new()
vb.add_theme_constant_override("separation", 8)
margin.add_child(vb)
var title := Label.new()
title.text = "CONFIGURAZIONE"
title.add_theme_font_size_override("font_size", 30)
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vb.add_child(title)
var entries := [
["start_time", "Tempo iniziale (s)", 1.0, 10.0, 0.1],
["min_time", "Tempo minimo (s)", 0.3, 3.0, 0.1],
["time_ramp", "Rampa tempo (s)", 30.0, 600.0, 10.0],
["score_ramp", "Rampa punteggio", 100.0, 10000.0, 100.0],
["points_per_combo", "Punti per combo", 1.0, 50.0, 1.0],
["combo_decay_threshold", "Soglia decay combo", 0.0, 30.0, 1.0],
["combo_decay_rate", "Rate decay combo", 0.0, 0.5, 0.01],
["difficulty_decay_rate", "Rate decay difficoltà", 0.0, 2.0, 0.05],
]
for e in entries:
rows[e[0]] = _build_row(vb, e[0], e[1], e[2], e[3], e[4])
# selettore curva punteggio
var ccurve := HBoxContainer.new()
ccurve.add_theme_constant_override("separation", 6)
vb.add_child(ccurve)
var clbl := Label.new()
clbl.text = "Curva punteggio"
clbl.custom_minimum_size.x = 230
ccurve.add_child(clbl)
curve_option = OptionButton.new()
curve_option.custom_minimum_size.x = 360
curve_option.add_item("Quadratica (attuale)")
curve_option.add_item("A scaglioni (ogni 5 tap)")
curve_option.add_item("Radice quadrata")
curve_option.add_item("Additiva (base + combo)")
curve_option.select(Settings.score_curve)
curve_option.item_selected.connect(func(idx: int): Settings.score_curve = idx)
ccurve.add_child(curve_option)
# pulsanti
var hb := HBoxContainer.new()
hb.add_theme_constant_override("separation", 8)
vb.add_child(hb)
var save := Button.new()
save.text = "Salva e riavvia"
save.pressed.connect(_on_save)
var reset := Button.new()
reset.text = "Ripristina default"
reset.pressed.connect(_on_reset)
var cancel := Button.new()
cancel.text = "Annulla"
cancel.pressed.connect(_on_cancel)
hb.add_child(save)
hb.add_child(reset)
hb.add_child(cancel)
func _build_row(parent: Node, key: String, label_text: String, mn: float, mx: float, step: float) -> Dictionary:
var hb := HBoxContainer.new()
hb.add_theme_constant_override("separation", 6)
parent.add_child(hb)
var lbl := Label.new()
lbl.text = label_text
lbl.custom_minimum_size.x = 230
hb.add_child(lbl)
var slider := HSlider.new()
slider.min_value = mn
slider.max_value = mx
slider.step = step
slider.custom_minimum_size.x = 260
slider.custom_minimum_size.y = 40
slider.add_theme_constant_override("grabber_radius", 14) # più facile da toccare
slider.value = Settings.get(key)
hb.add_child(slider)
var spin := SpinBox.new()
spin.min_value = mn
spin.max_value = mx
spin.step = step
spin.value = Settings.get(key)
spin.custom_minimum_size.x = 90
hb.add_child(spin)
slider.value_changed.connect(func(v: float):
spin.value = v
Settings.set(key, v))
spin.value_changed.connect(func(v: float):
slider.value = v
Settings.set(key, v))
return {"slider": slider, "spin": spin}
func show_menu() -> void:
# aggiorna i valori correnti ogni volta che si apre
for key in rows:
var val: float = Settings.get(key)
rows[key].slider.value = val
rows[key].spin.value = val
if curve_option:
curve_option.select(Settings.score_curve)
visible = true
get_tree().paused = true
func hide_menu() -> void:
visible = false
get_tree().paused = false
func _on_save() -> void:
Settings.save_settings()
hide_menu()
get_tree().call_deferred("reload_current_scene")
func _on_reset() -> void:
Settings.reset_defaults()
for key in rows:
var val: float = Settings.get(key)
rows[key].slider.value = val
rows[key].spin.value = val
if curve_option:
curve_option.select(Settings.score_curve)
func _on_cancel() -> void:
hide_menu()