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 zen_cb: CheckButton var gentle_cb: CheckButton 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], ["score_ramp", "Punteggio per velocità max", 100.0, 20000.0, 100.0], ["points_per_combo", "Punti per combo", 1.0, 50.0, 1.0], ["max_combo", "Combo massimo", 1.0, 20.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]) # opzioni accessibilità / neurodivergenza zen_cb = CheckButton.new() zen_cb.text = "Modalità Zen (senza tempo)" zen_cb.button_pressed = Settings.zen_mode zen_cb.toggled.connect(func(on: bool): Settings.zen_mode = on) vb.add_child(zen_cb) gentle_cb = CheckButton.new() gentle_cb.text = "Errori gentili (combo -1)" gentle_cb.button_pressed = Settings.gentle_errors gentle_cb.toggled.connect(func(on: bool): Settings.gentle_errors = on) vb.add_child(gentle_cb) # 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 zen_cb: zen_cb.button_pressed = Settings.zen_mode if gentle_cb: gentle_cb.button_pressed = Settings.gentle_errors 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 zen_cb: zen_cb.button_pressed = Settings.zen_mode if gentle_cb: gentle_cb.button_pressed = Settings.gentle_errors func _on_cancel() -> void: hide_menu()