import Phaser from 'phaser'; import { AudioPreferences, SettingsSceneData, loadAudioPreferences, saveAudioPreferences, } from '../game/preferences'; type ToggleDefinition = { key: keyof AudioPreferences; label: string; description: string; }; type ToggleVisuals = { background: Phaser.GameObjects.Rectangle; statusText: Phaser.GameObjects.Text; }; const TOGGLE_DEFINITIONS: ToggleDefinition[] = [ { key: 'musicEnabled', label: 'Musica del tavolo', description: 'Controlla il tappeto sonoro di sottofondo durante la partita.', }, { key: 'effectsEnabled', label: 'Effetti di gioco', description: 'Attiva prese, scope e segnali sonori senza toccare la musica.', }, ]; export class SettingsScene extends Phaser.Scene { private preferences: AudioPreferences = loadAudioPreferences(); private returnSceneKey = 'MenuScene'; private toggleVisuals = new Map(); constructor() { super({ key: 'SettingsScene' }); } create(data?: SettingsSceneData): void { const width = this.scale.width; const height = this.scale.height; this.preferences = loadAudioPreferences(); this.returnSceneKey = data?.returnSceneKey ?? 'MenuScene'; this.add.rectangle(0, 0, width, height, 0x123d22).setOrigin(0); this.add.rectangle(width / 2, height / 2, width - 120, height - 120, 0x0d2216, 0.88) .setStrokeStyle(2, 0xd9b75f, 0.45); this.add.text(width / 2, 120, 'Impostazioni audio', { fontFamily: 'Georgia, serif', fontSize: '46px', color: '#ffd700', stroke: '#000000', strokeThickness: 4, resolution: 2, }).setOrigin(0.5); this.add.text(width / 2, 176, 'Musica ed effetti sono separati: ogni scelta viene salvata subito e sarà usata nelle prossime partite.', { fontFamily: 'Georgia, serif', fontSize: '19px', color: '#d7ead1', resolution: 2, align: 'center', wordWrap: { width: 760 }, }).setOrigin(0.5); TOGGLE_DEFINITIONS.forEach((definition, index) => { this.createToggleRow(definition, width / 2, 286 + index * 132, 760, 96); }); this.add.text(width / 2, 556, 'Puoi tornare al menu in qualsiasi momento: la difficoltà si sceglie lì, l’audio resta salvato qui.', { fontFamily: 'Georgia, serif', fontSize: '16px', color: '#cfe5cd', resolution: 2, align: 'center', wordWrap: { width: 720 }, }).setOrigin(0.5); this.createButton(width / 2, height - 112, 280, 60, 'Torna al menu', 'Rientra alla schermata iniziale', () => { this.returnToMenu(); }); } private createToggleRow(definition: ToggleDefinition, x: number, y: number, width: number, height: number): void { const row = this.add.rectangle(x, y, width, height, 0x173323, 0.96) .setStrokeStyle(2, 0xcaa74a, 0.35) .setInteractive({ useHandCursor: true }); this.add.text(x - width / 2 + 28, y - 16, definition.label, { fontFamily: 'Georgia, serif', fontSize: '24px', color: '#ffffff', resolution: 2, }).setOrigin(0, 0.5); this.add.text(x - width / 2 + 28, y + 14, definition.description, { fontFamily: 'Georgia, serif', fontSize: '16px', color: '#d8ead2', resolution: 2, wordWrap: { width: 470 }, }).setOrigin(0, 0.5); const toggleBackground = this.add.rectangle(x + width / 2 - 106, y, 148, 46, 0x356b39, 1) .setStrokeStyle(2, 0xf5e1a4, 0.45); const statusText = this.add.text(x + width / 2 - 106, y, '', { fontFamily: 'Georgia, serif', fontSize: '20px', color: '#ffffff', resolution: 2, }).setOrigin(0.5); this.toggleVisuals.set(definition.key, { background: toggleBackground, statusText, }); row.on('pointerdown', () => { this.togglePreference(definition.key); }); row.on('pointerover', () => row.setFillStyle(0x1d402c, 1)); row.on('pointerout', () => row.setFillStyle(0x173323, 0.96)); this.refreshToggle(definition.key); } private createButton( x: number, y: number, width: number, height: number, label: string, subtitle: string, onClick: () => void, ): void { const button = this.add.rectangle(x, y, width, height, 0x1f6f78, 1) .setStrokeStyle(2, 0xf5e1a4, 0.4) .setInteractive({ useHandCursor: true }); this.add.text(x, y - 10, label, { fontFamily: 'Georgia, serif', fontSize: '21px', color: '#ffffff', stroke: '#000000', strokeThickness: 2, resolution: 2, }).setOrigin(0.5); this.add.text(x, y + 14, subtitle, { fontFamily: 'Georgia, serif', fontSize: '13px', color: '#f7f1d5', resolution: 2, align: 'center', }).setOrigin(0.5); button.on('pointerover', () => button.setFillStyle(0x2f8f99)); button.on('pointerout', () => button.setFillStyle(0x1f6f78)); button.on('pointerdown', onClick); } private togglePreference(key: keyof AudioPreferences): void { this.preferences = saveAudioPreferences({ ...this.preferences, [key]: !this.preferences[key], }); this.refreshToggle(key); } private refreshToggle(key: keyof AudioPreferences): void { const visuals = this.toggleVisuals.get(key); if (!visuals) { return; } const enabled = this.preferences[key]; visuals.background.setFillStyle(enabled ? 0x356b39 : 0x7a2f2f); visuals.statusText.setText(enabled ? 'Attivo' : 'Disattivato'); } private returnToMenu(): void { this.cameras.main.fadeOut(250, 0, 30, 0); this.cameras.main.once('camerafadeoutcomplete', () => { this.scene.start(this.returnSceneKey); }); } }