Auto-sync: 20260315_030000

This commit is contained in:
Paolo 2026-03-15 03:00:01 +01:00
parent 6e5fb8a984
commit 8ef703c082
7 changed files with 177 additions and 73 deletions

BIN
assets/.DS_Store vendored

Binary file not shown.

BIN
assets/images/grimorio.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View file

@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
enum AppThemeType { doodle, wood, cyberpunk, arcade, grimorio, music } // <-- Aggiunto 'music' enum AppThemeType { doodle, wood, cyberpunk, arcade, grimorio, music }
class ThemeColors { class ThemeColors {
final Color background; final Color background;
@ -45,16 +45,15 @@ class AppColors {
); );
static const ThemeColors grimorio = ThemeColors( static const ThemeColors grimorio = ThemeColors(
background: Color(0xFF1E112A), gridLine: Color(0xFF8D6E63), background: Color(0xFF1E112A), gridLine: Colors.black, // <--- Modificato in nero!
playerRed: Color(0xFFE91E63), playerBlue: Color(0xFF4FC3F7), text: Color(0xFFFFF3E0), playerRed: Color(0xFFE91E63), playerBlue: Color(0xFF4FC3F7), text: Color(0xFFFFF3E0),
); );
// --- NUOVO TEMA MUSICA ---
static const ThemeColors music = ThemeColors( static const ThemeColors music = ThemeColors(
background: Color(0xFF120B29), // Viola scuro (stile Synthwave) background: Color(0xFF120B29),
gridLine: Color(0xFF6A1B9A), // Viola elettrico gridLine: Color(0xFF6A1B9A),
playerRed: Color(0xFFFF2A6D), // Rosa acceso playerRed: Color(0xFFFF2A6D),
playerBlue: Color(0xFF05D5FF), // Ciano playerBlue: Color(0xFF05D5FF),
text: Color(0xFFE0E0E0), text: Color(0xFFE0E0E0),
); );
@ -78,7 +77,7 @@ class ThemeIcons {
case AppThemeType.cyberpunk: return FontAwesomeIcons.microchip; case AppThemeType.cyberpunk: return FontAwesomeIcons.microchip;
case AppThemeType.arcade: return FontAwesomeIcons.coins; case AppThemeType.arcade: return FontAwesomeIcons.coins;
case AppThemeType.grimorio: return FontAwesomeIcons.crown; case AppThemeType.grimorio: return FontAwesomeIcons.crown;
case AppThemeType.music: return FontAwesomeIcons.compactDisc; // CD/Vinile per i punti case AppThemeType.music: return FontAwesomeIcons.compactDisc;
} }
} }
@ -89,7 +88,7 @@ class ThemeIcons {
case AppThemeType.cyberpunk: return FontAwesomeIcons.bug; case AppThemeType.cyberpunk: return FontAwesomeIcons.bug;
case AppThemeType.arcade: return FontAwesomeIcons.ghost; case AppThemeType.arcade: return FontAwesomeIcons.ghost;
case AppThemeType.grimorio: return FontAwesomeIcons.hatWizard; case AppThemeType.grimorio: return FontAwesomeIcons.hatWizard;
case AppThemeType.music: return FontAwesomeIcons.volumeXmark; // Muto/Errore per la bomba case AppThemeType.music: return FontAwesomeIcons.volumeXmark;
} }
} }
@ -100,7 +99,7 @@ class ThemeIcons {
case AppThemeType.cyberpunk: return FontAwesomeIcons.networkWired; case AppThemeType.cyberpunk: return FontAwesomeIcons.networkWired;
case AppThemeType.arcade: return FontAwesomeIcons.shuffle; case AppThemeType.arcade: return FontAwesomeIcons.shuffle;
case AppThemeType.grimorio: return FontAwesomeIcons.hurricane; case AppThemeType.grimorio: return FontAwesomeIcons.hurricane;
case AppThemeType.music: return FontAwesomeIcons.sliders; // Fader da DJ case AppThemeType.music: return FontAwesomeIcons.sliders;
} }
} }
@ -111,7 +110,7 @@ class ThemeIcons {
case AppThemeType.cyberpunk: return FontAwesomeIcons.robot; case AppThemeType.cyberpunk: return FontAwesomeIcons.robot;
case AppThemeType.arcade: return FontAwesomeIcons.gamepad; case AppThemeType.arcade: return FontAwesomeIcons.gamepad;
case AppThemeType.grimorio: return FontAwesomeIcons.masksTheater; case AppThemeType.grimorio: return FontAwesomeIcons.masksTheater;
case AppThemeType.music: return FontAwesomeIcons.headphones; // Cuffie per il Jolly case AppThemeType.music: return FontAwesomeIcons.headphones;
} }
} }
@ -122,17 +121,17 @@ class ThemeIcons {
case AppThemeType.cyberpunk: return FontAwesomeIcons.shieldHalved; case AppThemeType.cyberpunk: return FontAwesomeIcons.shieldHalved;
case AppThemeType.arcade: return FontAwesomeIcons.powerOff; case AppThemeType.arcade: return FontAwesomeIcons.powerOff;
case AppThemeType.grimorio: return FontAwesomeIcons.meteor; case AppThemeType.grimorio: return FontAwesomeIcons.meteor;
case AppThemeType.music: return FontAwesomeIcons.pause; // Pausa per il blocco vuoto case AppThemeType.music: return FontAwesomeIcons.pause;
} }
} }
static IconData ice(AppThemeType type) { static IconData ice(AppThemeType type) {
if (type == AppThemeType.music) return FontAwesomeIcons.music; // Nota musicale ghiacciata if (type == AppThemeType.music) return FontAwesomeIcons.music;
return FontAwesomeIcons.snowflake; return FontAwesomeIcons.snowflake;
} }
static IconData multiplier(AppThemeType type) { static IconData multiplier(AppThemeType type) {
if (type == AppThemeType.music) return FontAwesomeIcons.forwardFast; // Fast Forward per il x2 if (type == AppThemeType.music) return FontAwesomeIcons.forwardFast;
return FontAwesomeIcons.bolt; return FontAwesomeIcons.bolt;
} }
} }

View file

@ -54,28 +54,72 @@ class BoardPainter extends CustomPainter {
double offset = spacing / 2; double offset = spacing / 2;
Offset getScreenPos(int x, int y) => Offset(x * spacing + offset, y * spacing + offset); Offset getScreenPos(int x, int y) => Offset(x * spacing + offset, y * spacing + offset);
// --- NUOVO SFONDO LUMINOSO SAGOMATO (Solo per tema Musica) --- // =======================================================================
if (themeType == AppThemeType.music) { // 1. CREAZIONE DELLA SAGOMA DELL'ARENA (SFONDO E BORDO)
// =======================================================================
Path arenaShape = Path(); Path arenaShape = Path();
// Uniamo la forma di ogni box giocabile per creare il tappeto bool isFirst = true;
// Uniamo la forma di ogni box giocabile per creare un'unica sagoma
for (var box in board.boxes) { for (var box in board.boxes) {
if (box.type != BoxType.invisible) { // Ignora i buchi if (box.type != BoxType.invisible) { // Ignora i buchi
Offset p1 = getScreenPos(box.x, box.y); Offset p1 = getScreenPos(box.x, box.y);
Offset p2 = getScreenPos(box.x + 1, box.y + 1); Offset p2 = getScreenPos(box.x + 1, box.y + 1);
arenaShape.addRect(Rect.fromPoints(p1, p2)); Path boxPath = Path()..addRect(Rect.fromPoints(p1, p2));
if (isFirst) {
arenaShape = boxPath;
isFirst = false;
} else {
arenaShape = Path.combine(PathOperation.union, arenaShape, boxPath);
}
} }
} }
// Disegniamo lo sfondo unito, chiaro e con un po' di blur // --- DISEGNO DELLO SFONDO LUMINOSO ---
canvas.drawPath( final fillPaint = Paint()
arenaShape,
Paint()
..color = Colors.white.withOpacity(0.08) // Colore chiarissimo
..style = PaintingStyle.fill ..style = PaintingStyle.fill
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 10.0), // Effetto stacco/glow ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 10.0);
);
if (themeType == AppThemeType.music) {
fillPaint.color = Colors.white.withOpacity(0.08);
canvas.drawPath(arenaShape, fillPaint);
} else if (themeType == AppThemeType.wood) {
fillPaint.color = Colors.black.withOpacity(0.3);
fillPaint.maskFilter = const MaskFilter.blur(BlurStyle.normal, 15.0);
canvas.drawPath(arenaShape, fillPaint);
} else if (themeType == AppThemeType.cyberpunk) {
fillPaint.color = theme.playerBlue.withOpacity(0.1);
canvas.drawPath(arenaShape, fillPaint);
} }
// -----------------------------------------------------------
// --- DISEGNO DEL BORDO ESTERNO SOTTILE ---
double baseStroke = themeType == AppThemeType.grimorio ? 6.0 : 4.0;
if (themeType == AppThemeType.doodle) baseStroke = 2.5;
final outlinePaint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = baseStroke * 0.5 // Moltiplicato per 0.5 = grande la metà delle linee interne!
..strokeJoin = StrokeJoin.round;
if (themeType == AppThemeType.cyberpunk) {
outlinePaint.color = theme.gridLine;
outlinePaint.maskFilter = MaskFilter.blur(BlurStyle.solid, 4.0 * blinkValue.clamp(0.1, 1.0));
}
else if (themeType == AppThemeType.arcade) { outlinePaint.color = Colors.white; }
else if (themeType == AppThemeType.grimorio) { outlinePaint.color = theme.gridLine.withOpacity(0.6); }
else if (themeType == AppThemeType.music) { outlinePaint.color = Colors.black; } // Rimosso lo spessore forzato a 8.0!
else if (themeType == AppThemeType.doodle) { outlinePaint.color = const Color(0xFF111122); } // Rimosso lo spessore forzato a 6.0!
else if (themeType == AppThemeType.wood) {
outlinePaint.color = const Color(0xFF3E2723);
outlinePaint.maskFilter = const MaskFilter.blur(BlurStyle.normal, 2.0);
}
else { outlinePaint.color = theme.gridLine.withOpacity(0.8); }
// Disegniamo il contorno
canvas.drawPath(arenaShape, outlinePaint);
// =======================================================================
for (var box in board.boxes) { for (var box in board.boxes) {
Offset p1 = getScreenPos(box.x, box.y); Offset p1 = getScreenPos(box.x, box.y);

View file

@ -294,7 +294,8 @@ class _GameScreenState extends State<GameScreen> with TickerProviderStateMixin {
if (themeType == AppThemeType.doodle) bgImage = 'assets/images/doodle_bg.jpg'; if (themeType == AppThemeType.doodle) bgImage = 'assets/images/doodle_bg.jpg';
if (themeType == AppThemeType.cyberpunk) bgImage = 'assets/images/cyber_bg.jpg'; if (themeType == AppThemeType.cyberpunk) bgImage = 'assets/images/cyber_bg.jpg';
if (themeType == AppThemeType.music) bgImage = 'assets/images/music_bg.jpg'; if (themeType == AppThemeType.music) bgImage = 'assets/images/music_bg.jpg';
if (themeType == AppThemeType.arcade) bgImage = 'assets/images/arcade.jpg'; // <-- SFONDO ARCADE AGGIUNTO if (themeType == AppThemeType.arcade) bgImage = 'assets/images/arcade.jpg';
if (themeType == AppThemeType.grimorio) bgImage = 'assets/images/grimorio.jpg';
Color indicatorColor = themeType == AppThemeType.cyberpunk || themeType == AppThemeType.arcade || themeType == AppThemeType.music ? Colors.white : Colors.black; Color indicatorColor = themeType == AppThemeType.cyberpunk || themeType == AppThemeType.arcade || themeType == AppThemeType.music ? Colors.white : Colors.black;
@ -327,7 +328,8 @@ class _GameScreenState extends State<GameScreen> with TickerProviderStateMixin {
Expanded( Expanded(
child: Center( child: Center(
child: Padding( child: Padding(
padding: const EdgeInsets.all(10.0), // PADDING RIDOTTO AL MINIMO: permette alla griglia di guadagnare pixel preziosi per allargarsi/alzarsi!
padding: const EdgeInsets.symmetric(horizontal: 2.0, vertical: 2.0),
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
int cols = gameController.board.columns + 1; int cols = gameController.board.columns + 1;
@ -342,15 +344,16 @@ class _GameScreenState extends State<GameScreen> with TickerProviderStateMixin {
width: actualWidth, height: actualHeight, width: actualWidth, height: actualHeight,
child: Stack( child: Stack(
children: [ children: [
// --- IL VERO SFONDO SFOCATO SAGOMATO --- // --- IL VERO SFONDO SFOCATO SAGOMATO (ORA PER TUTTI I TEMI) ---
if (themeType == AppThemeType.music)
Positioned.fill( Positioned.fill(
child: ClipPath( child: ClipPath(
clipper: _ArenaClipper(gameController.board), clipper: _ArenaClipper(gameController.board),
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 8.0, sigmaY: 8.0), filter: ImageFilter.blur(sigmaX: 8.0, sigmaY: 8.0),
child: Container( child: Container(
color: Colors.white.withOpacity(0.08), color: themeType == AppThemeType.doodle
? Colors.black.withOpacity(0.05)
: Colors.white.withOpacity(0.12),
), ),
), ),
), ),
@ -384,7 +387,8 @@ class _GameScreenState extends State<GameScreen> with TickerProviderStateMixin {
), ),
Padding( Padding(
padding: const EdgeInsets.only(bottom: 20.0, left: 20.0, right: 20.0), // PADDING RIDOTTO IN BASSO: 10 al posto di 20, per far esplodere la griglia verticalmente
padding: const EdgeInsets.only(bottom: 10.0, left: 20.0, right: 20.0, top: 5.0),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@ -456,8 +460,8 @@ class _GameScreenState extends State<GameScreen> with TickerProviderStateMixin {
), ),
), ),
// 4. Patina scura (Cyberpunk, Music, Arcade) // 4. Patina scura (Cyberpunk, Music, Arcade e Grimorio)
if (bgImage != null && (themeType == AppThemeType.cyberpunk || themeType == AppThemeType.music || themeType == AppThemeType.arcade)) if (bgImage != null && (themeType == AppThemeType.cyberpunk || themeType == AppThemeType.music || themeType == AppThemeType.arcade || themeType == AppThemeType.grimorio))
Positioned.fill( Positioned.fill(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(

View file

@ -1,5 +1,5 @@
// =========================================================================== // ===========================================================================
// FILE: lib/ui/home/dialogs/dialog.dart // FILE: lib/ui/home/dialog.dart
// =========================================================================== // ===========================================================================
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -8,11 +8,11 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart';
import '../../../core/theme_manager.dart'; import '../../core/theme_manager.dart';
import '../../../core/app_colors.dart'; import '../../core/app_colors.dart';
import '../../../l10n/app_localizations.dart'; import '../../l10n/app_localizations.dart';
import '../../../widgets/painters.dart'; import '../../widgets/painters.dart';
import '../../../widgets/cyber_border.dart'; import '../../widgets/cyber_border.dart';
// =========================================================================== // ===========================================================================
// 1. DIALOGO MISSIONI (QUESTS) // 1. DIALOGO MISSIONI (QUESTS)
@ -158,14 +158,29 @@ class LeaderboardDialog extends StatelessWidget {
return Center(child: Text("Ancora nessun campione...", style: TextStyle(color: theme.text.withOpacity(0.5)))); return Center(child: Text("Ancora nessun campione...", style: TextStyle(color: theme.text.withOpacity(0.5))));
} }
final docs = snapshot.data!.docs; // 1. ESTRAIAMO TUTTI I DOCUMENTI
final rawDocs = snapshot.data!.docs;
// 2. APPLICHIAMO IL FILTRO PER NASCONDERE "PAOLO"
final filteredDocs = rawDocs.where((doc) {
var data = doc.data() as Map<String, dynamic>;
String name = (data['name'] ?? '').toString().toUpperCase();
return name != 'PAOLO';
}).toList();
// 3. SE DOPO IL FILTRO NON C'E' NESSUNO
if (filteredDocs.isEmpty) {
return Center(child: Text("Ancora nessun campione...", style: TextStyle(color: theme.text.withOpacity(0.5))));
}
return ListView.builder( return ListView.builder(
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
itemCount: docs.length, itemCount: filteredDocs.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
var data = docs[index].data() as Map<String, dynamic>; var doc = filteredDocs[index];
var data = doc.data() as Map<String, dynamic>;
String? myUid = FirebaseAuth.instance.currentUser?.uid; String? myUid = FirebaseAuth.instance.currentUser?.uid;
bool isMe = docs[index].id == myUid; bool isMe = doc.id == myUid;
return Container( return Container(
margin: const EdgeInsets.only(bottom: 8), margin: const EdgeInsets.only(bottom: 8),
@ -230,9 +245,50 @@ class TutorialDialog extends StatelessWidget {
final themeType = themeManager.currentThemeType; final themeType = themeManager.currentThemeType;
Color inkColor = const Color(0xFF111122); Color inkColor = const Color(0xFF111122);
String goldLabel = themeType == AppThemeType.grimorio ? "CORONA:" : "ORO:"; // ETICHETTE DINAMICHE PER I POTENZIAMENTI
String bombLabel = themeType == AppThemeType.grimorio ? "STREGA:" : "BOMBA:"; String goldLabel = "ORO:";
String jokerLabel = themeType == AppThemeType.grimorio ? "GIULLARE:" : "JOLLY:"; String bombLabel = "BOMBA:";
String swapLabel = "SCAMBIO:";
String jokerLabel = "JOLLY:";
String iceLabel = "GHIACCIO:";
String multiplierLabel = "x2:";
String blockLabel = "BUCO NERO:";
if (themeType == AppThemeType.grimorio) {
goldLabel = "CORONA:";
bombLabel = "STREGA:";
jokerLabel = "GIULLARE:";
swapLabel = "TORNADO:";
multiplierLabel = "FULMINE:";
blockLabel = "METEORITE:";
} else if (themeType == AppThemeType.music) {
goldLabel = "DISCO D'ORO:";
bombLabel = "MUTO:";
jokerLabel = "DJ:";
swapLabel = "MIXER:";
iceLabel = "NOTA:";
multiplierLabel = "AVANTI VELOCE:";
blockLabel = "PAUSA:";
} else if (themeType == AppThemeType.arcade) {
goldLabel = "GETTONE:";
bombLabel = "FANTASMA:";
jokerLabel = "GAMEPAD:";
swapLabel = "SHUFFLE:";
blockLabel = "POWER OFF:";
} else if (themeType == AppThemeType.cyberpunk) {
goldLabel = "CHIP:";
bombLabel = "VIRUS:";
jokerLabel = "BOT:";
swapLabel = "NETWORK:";
blockLabel = "FIREWALL:";
} else if (themeType == AppThemeType.wood) {
goldLabel = "GEMMA:";
bombLabel = "FUOCO:";
jokerLabel = "CHIAVE:";
blockLabel = "DIVIETO:";
} else if (themeType == AppThemeType.doodle) {
bombLabel = "VIRUS:";
}
Widget dialogContent = themeType == AppThemeType.doodle Widget dialogContent = themeType == AppThemeType.doodle
? Transform.rotate( ? Transform.rotate(
@ -260,15 +316,15 @@ class TutorialDialog extends StatelessWidget {
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.bomb(themeType), iconColor: Colors.deepPurple, text: "$bombLabel Non chiuderlo! Perderai -1 Punto.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.bomb(themeType), iconColor: Colors.deepPurple, text: "$bombLabel Non chiuderlo! Perderai -1 Punto.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.swap(themeType), iconColor: Colors.purpleAccent, text: "SCAMBIO: Inverte istantaneamente i punteggi dei giocatori.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.swap(themeType), iconColor: Colors.purpleAccent, text: "$swapLabel Inverte istantaneamente i punteggi dei giocatori.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.joker(themeType), iconColor: Colors.green.shade600, text: "$jokerLabel Scegli dove nasconderlo a inizio partita. Se lo chiudi tu +2, se lo chiude l'avversario -1!", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.joker(themeType), iconColor: Colors.green.shade600, text: "$jokerLabel Scegli dove nasconderlo a inizio partita. Se lo chiudi tu +2, se lo chiude l'avversario -1!", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.ice(themeType), iconColor: Colors.cyanAccent, text: "GHIACCIO: Devi cliccarlo due volte per poterlo rompere e chiudere.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.ice(themeType), iconColor: Colors.cyanAccent, text: "$iceLabel Devi cliccarlo due volte per poterlo rompere e chiudere.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.multiplier(themeType), iconColor: Colors.yellowAccent, text: "x2: Non dà punti, ma raddoppia il punteggio della prossima casella che chiudi!", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.multiplier(themeType), iconColor: Colors.yellowAccent, text: "$multiplierLabel Non dà punti, ma raddoppia il punteggio della prossima casella che chiudi!", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.block(themeType), iconColor: Colors.grey, text: "BUCO NERO: Questa casella non esiste. Se la chiudi perdi il turno.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.block(themeType), iconColor: Colors.grey, text: "$blockLabel Questa casella non esiste. Se la chiudi perdi il turno.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 25), const SizedBox(height: 25),
Center( Center(
@ -317,15 +373,15 @@ class TutorialDialog extends StatelessWidget {
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.bomb(themeType), iconColor: themeType == AppThemeType.cyberpunk || themeType == AppThemeType.arcade ? Colors.greenAccent : Colors.deepPurple, text: "$bombLabel Non chiuderlo! Perderai -1 Punto.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.bomb(themeType), iconColor: themeType == AppThemeType.cyberpunk || themeType == AppThemeType.arcade ? Colors.greenAccent : Colors.deepPurple, text: "$bombLabel Non chiuderlo! Perderai -1 Punto.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.swap(themeType), iconColor: Colors.purpleAccent, text: "SCAMBIO: Inverte istantaneamente i punteggi dei giocatori.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.swap(themeType), iconColor: Colors.purpleAccent, text: "$swapLabel Inverte istantaneamente i punteggi dei giocatori.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.joker(themeType), iconColor: theme.playerBlue, text: "$jokerLabel Scegli dove nasconderlo a inizio partita. Se lo chiudi tu +2, se lo chiude l'avversario -1!", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.joker(themeType), iconColor: theme.playerBlue, text: "$jokerLabel Scegli dove nasconderlo a inizio partita. Se lo chiudi tu +2, se lo chiude l'avversario -1!", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.ice(themeType), iconColor: Colors.cyanAccent, text: "GHIACCIO: Devi cliccarlo due volte per poterlo rompere e chiudere.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.ice(themeType), iconColor: Colors.cyanAccent, text: "$iceLabel Devi cliccarlo due volte per poterlo rompere e chiudere.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.multiplier(themeType), iconColor: Colors.yellowAccent, text: "x2: Non dà punti, ma raddoppia il punteggio della prossima casella che chiudi!", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.multiplier(themeType), iconColor: Colors.yellowAccent, text: "$multiplierLabel Non dà punti, ma raddoppia il punteggio della prossima casella che chiudi!", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 10), const SizedBox(height: 10),
TutorialStep(icon: ThemeIcons.block(themeType), iconColor: Colors.grey, text: "BUCO NERO: Questa casella non esiste. Se la chiudi perdi il turno.", themeType: themeType, inkColor: inkColor, theme: theme), TutorialStep(icon: ThemeIcons.block(themeType), iconColor: Colors.grey, text: "$blockLabel Questa casella non esiste. Se la chiudi perdi il turno.", themeType: themeType, inkColor: inkColor, theme: theme),
const SizedBox(height: 30), const SizedBox(height: 30),
SizedBox( SizedBox(

View file

@ -28,7 +28,7 @@ import '../../widgets/painters.dart';
import '../../widgets/cyber_border.dart'; import '../../widgets/cyber_border.dart';
import '../../widgets/music_theme_widgets.dart'; import '../../widgets/music_theme_widgets.dart';
import '../../widgets/home_buttons.dart'; import '../../widgets/home_buttons.dart';
import '../../widgets/custom_settings_button.dart'; // <--- IMPORTIAMO I NOSTRI BOTTONI import '../../widgets/custom_settings_button.dart';
import 'dialog.dart'; import 'dialog.dart';
// =========================================================================== // ===========================================================================
@ -593,6 +593,7 @@ class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
if (themeType == AppThemeType.cyberpunk) bgImage = 'assets/images/cyber_bg.jpg'; if (themeType == AppThemeType.cyberpunk) bgImage = 'assets/images/cyber_bg.jpg';
if (themeType == AppThemeType.music) bgImage = 'assets/images/music_bg.jpg'; if (themeType == AppThemeType.music) bgImage = 'assets/images/music_bg.jpg';
if (themeType == AppThemeType.arcade) bgImage = 'assets/images/arcade.jpg'; if (themeType == AppThemeType.arcade) bgImage = 'assets/images/arcade.jpg';
if (themeType == AppThemeType.grimorio) bgImage = 'assets/images/grimorio.jpg'; // Aggiunto Grimorio
int wins = StorageService.instance.wins; int wins = StorageService.instance.wins;
int losses = StorageService.instance.losses; int losses = StorageService.instance.losses;
@ -622,7 +623,7 @@ class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// BLOCCO SINISTRO: AVATAR E NOME // BLOCCO SINISTRO: AVATAR E NOME
Expanded( // Permette di occupare lo spazio necessario senza spingere la destra Expanded(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -887,8 +888,8 @@ class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
), ),
), ),
// 4. Patina scura (Cyberpunk, Music e Arcade) // 4. Patina scura (Cyberpunk, Music, Arcade e Grimorio)
if (bgImage != null && (themeType == AppThemeType.cyberpunk || themeType == AppThemeType.music || themeType == AppThemeType.arcade)) if (bgImage != null && (themeType == AppThemeType.cyberpunk || themeType == AppThemeType.music || themeType == AppThemeType.arcade || themeType == AppThemeType.grimorio))
Positioned.fill( Positioned.fill(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(