tetraq/lib/widgets/game_over_dialog.dart

222 lines
9.3 KiB
Dart
Raw Normal View History

2026-03-11 22:00:01 +01:00
// ===========================================================================
// FILE: lib/widgets/game_over_dialog.dart
// ===========================================================================
2026-02-27 23:35:54 +01:00
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../logic/game_controller.dart';
import '../core/theme_manager.dart';
import '../core/app_colors.dart';
2026-03-11 22:00:01 +01:00
import '../services/storage_service.dart';
2026-02-27 23:35:54 +01:00
class GameOverDialog extends StatelessWidget {
const GameOverDialog({super.key});
@override
Widget build(BuildContext context) {
final game = context.read<GameController>();
final themeManager = context.read<ThemeManager>();
final theme = themeManager.currentColors;
final themeType = themeManager.currentThemeType;
int red = game.board.scoreRed;
int blue = game.board.scoreBlue;
bool playerBeatCPU = game.isVsCPU && red > blue;
2026-03-11 22:00:01 +01:00
String myName = StorageService.instance.playerName.toUpperCase();
if (myName.isEmpty) myName = "TU";
2026-02-27 23:35:54 +01:00
// --- LOGICA NOMI ---
2026-03-11 22:00:01 +01:00
String nameRed = myName;
String nameBlue = themeType == AppThemeType.cyberpunk || themeType == AppThemeType.arcade ? "VERDE" : "BLU";
2026-02-27 23:35:54 +01:00
if (game.isOnline) {
nameRed = game.onlineHostName.toUpperCase();
nameBlue = game.onlineGuestName.toUpperCase();
} else if (game.isVsCPU) {
2026-03-11 22:00:01 +01:00
nameRed = myName;
2026-02-27 23:35:54 +01:00
nameBlue = "CPU";
}
// --- DETERMINA IL VINCITORE ---
String winnerText = "";
Color winnerColor = theme.text;
if (red > blue) {
winnerText = "VINCE $nameRed!";
winnerColor = theme.playerRed;
} else if (blue > red) {
winnerText = "VINCE $nameBlue!";
winnerColor = theme.playerBlue;
} else {
winnerText = "PAREGGIO!";
winnerColor = theme.text;
}
return AlertDialog(
backgroundColor: theme.background,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(color: winnerColor.withOpacity(0.5), width: 2),
),
title: Text("FINE PARTITA", textAlign: TextAlign.center, style: TextStyle(color: theme.text, fontWeight: FontWeight.bold, fontSize: 22)),
2026-03-20 14:00:00 +01:00
content: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(winnerText, textAlign: TextAlign.center, style: TextStyle(fontSize: 26, fontWeight: FontWeight.w900, color: winnerColor)),
const SizedBox(height: 20),
Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
color: theme.text.withOpacity(0.05),
borderRadius: BorderRadius.circular(15),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text("$nameRed: $red", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: theme.playerRed)),
Text(" - ", style: TextStyle(fontSize: 18, color: theme.text)),
Text("$nameBlue: $blue", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: theme.playerBlue)),
],
),
2026-02-27 23:35:54 +01:00
),
2026-03-20 14:00:00 +01:00
if (game.isVsCPU) ...[
const SizedBox(height: 15),
Text("Difficoltà CPU: Livello ${game.cpuLevel}", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: theme.text.withOpacity(0.7))),
],
// --- SEZIONE LEVEL UP E ROADMAP DINAMICA ---
if (game.hasLeveledUp && game.unlockedRewards.isNotEmpty) ...[
const SizedBox(height: 30),
const Divider(),
const SizedBox(height: 15),
Container(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 20),
decoration: BoxDecoration(
color: Colors.amber.withOpacity(0.2),
borderRadius: BorderRadius.circular(30),
border: Border.all(color: Colors.amber, width: 2)
),
child: Text("🎉 LIVELLO ${game.newlyReachedLevel}! 🎉", style: const TextStyle(color: Colors.amber, fontWeight: FontWeight.w900, fontSize: 18)),
),
const SizedBox(height: 15),
...game.unlockedRewards.map((reward) => Container(
margin: const EdgeInsets.only(bottom: 10),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: (reward['color'] as Color).withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: (reward['color'] as Color).withOpacity(0.5), width: 1.5),
),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: (reward['color'] as Color).withOpacity(0.2),
shape: BoxShape.circle,
),
child: Icon(reward['icon'], color: reward['color'], size: 28),
),
const SizedBox(width: 15),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(reward['title'], style: TextStyle(color: reward['color'], fontWeight: FontWeight.w900, fontSize: 16)),
const SizedBox(height: 4),
Text(reward['desc'], style: TextStyle(color: theme.text.withOpacity(0.9), fontSize: 12, height: 1.3)),
],
)
)
]
)
)),
]
// ---------------------------------------------
],
),
2026-02-27 23:35:54 +01:00
),
actionsPadding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 10),
actionsAlignment: MainAxisAlignment.center,
actions: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (playerBeatCPU)
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: winnerColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 15),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
elevation: 5,
),
onPressed: () {
Navigator.pop(context);
game.increaseLevelAndRestart();
},
child: const Text("PROSSIMO LIVELLO ➔", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
)
else if (game.isOnline)
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: winnerColor == theme.text ? theme.playerBlue : winnerColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 15),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
elevation: 5,
),
onPressed: () {
Navigator.pop(context);
if (game.board.isGameOver) {
game.requestRematch();
}
},
child: const Text("RIGIOCA ONLINE", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16, letterSpacing: 1.5)),
)
else
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: winnerColor == theme.text ? theme.playerBlue : winnerColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 15),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
elevation: 5,
),
onPressed: () {
Navigator.pop(context);
game.startNewGame(game.board.radius, vsCPU: game.isVsCPU);
},
child: const Text("RIGIOCA", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16, letterSpacing: 2)),
),
const SizedBox(height: 12),
OutlinedButton(
style: OutlinedButton.styleFrom(
foregroundColor: theme.text,
side: BorderSide(color: theme.text.withOpacity(0.3), width: 2),
padding: const EdgeInsets.symmetric(vertical: 15),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
),
onPressed: () {
if (game.isOnline) {
game.disconnectOnlineGame();
}
Navigator.pop(context);
Navigator.pop(context);
},
child: Text("TORNA AL MENU", style: TextStyle(fontWeight: FontWeight.bold, color: theme.text, fontSize: 14, letterSpacing: 1.5)),
),
],
)
],
);
}
}