193 lines
5.6 KiB
TypeScript
193 lines
5.6 KiB
TypeScript
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<keyof AudioPreferences, ToggleVisuals>();
|
||
|
||
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);
|
||
});
|
||
}
|
||
} |