tetraq/lib/ui/game/score_board.dart

201 lines
8.2 KiB
Dart
Raw Permalink Normal View History

2026-03-01 20:59:06 +01:00
// ===========================================================================
// FILE: lib/ui/game/score_board.dart
// ===========================================================================
2026-02-27 23:35:54 +01:00
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
2026-03-13 23:00:01 +01:00
import 'package:google_fonts/google_fonts.dart';
2026-02-27 23:35:54 +01:00
import '../../logic/game_controller.dart';
import '../../models/game_board.dart';
import '../../core/theme_manager.dart';
import '../../services/audio_service.dart';
import '../../core/app_colors.dart';
2026-03-11 22:00:01 +01:00
import '../../services/storage_service.dart';
2026-03-14 19:00:00 +01:00
import '../home/dialog.dart'; // <--- IMPORTANTE: Importa il TutorialDialog
2026-02-27 23:35:54 +01:00
2026-03-13 23:00:01 +01:00
TextStyle _getTextStyle(AppThemeType themeType, TextStyle baseStyle) {
if (themeType == AppThemeType.doodle) {
return GoogleFonts.permanentMarker(textStyle: baseStyle);
} else if (themeType == AppThemeType.arcade) {
return GoogleFonts.pressStart2p(textStyle: baseStyle.copyWith(
fontSize: baseStyle.fontSize != null ? baseStyle.fontSize! * 0.75 : null,
letterSpacing: 0.5,
));
} else if (themeType == AppThemeType.grimorio) {
return GoogleFonts.cinzelDecorative(textStyle: baseStyle.copyWith(fontWeight: FontWeight.bold));
}
return baseStyle;
}
2026-02-27 23:35:54 +01:00
class ScoreBoard extends StatefulWidget {
const ScoreBoard({super.key});
@override
State<ScoreBoard> createState() => _ScoreBoardState();
}
class _ScoreBoardState extends State<ScoreBoard> {
@override
Widget build(BuildContext context) {
final controller = context.watch<GameController>();
final themeManager = context.watch<ThemeManager>();
final theme = themeManager.currentColors;
final themeType = themeManager.currentThemeType;
int redScore = controller.board.scoreRed;
int blueScore = controller.board.scoreBlue;
bool isRedTurn = controller.board.currentPlayer == Player.red;
bool isMuted = AudioService.instance.isMuted;
2026-03-11 22:00:01 +01:00
String myName = StorageService.instance.playerName.toUpperCase();
if (myName.isEmpty) myName = "TU";
String nameRed = myName;
String nameBlue = themeType == AppThemeType.cyberpunk || themeType == AppThemeType.arcade ? "VERDE" : "BLU";
2026-02-27 23:35:54 +01:00
if (controller.isOnline) {
nameRed = controller.onlineHostName.toUpperCase();
nameBlue = controller.onlineGuestName.toUpperCase();
} else if (controller.isVsCPU) {
2026-03-11 22:00:01 +01:00
nameRed = myName;
2026-02-27 23:35:54 +01:00
nameBlue = "CPU";
}
return Container(
padding: const EdgeInsets.only(top: 10, bottom: 20, left: 20, right: 20),
decoration: BoxDecoration(
2026-03-13 23:00:01 +01:00
color: themeType == AppThemeType.doodle ? theme.background : theme.background.withOpacity(0.95),
2026-02-27 23:35:54 +01:00
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
offset: const Offset(0, 4),
blurRadius: 8,
),
],
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
2026-03-13 23:00:01 +01:00
_PlayerScore(color: theme.playerRed, score: redScore, isTurn: isRedTurn, textColor: theme.text, title: nameRed, themeType: themeType),
2026-02-27 23:35:54 +01:00
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"TETRAQ",
2026-03-13 23:00:01 +01:00
style: _getTextStyle(themeType, TextStyle(
2026-02-27 23:35:54 +01:00
fontSize: 24,
fontWeight: FontWeight.w900,
color: theme.text,
letterSpacing: 4,
2026-03-13 23:00:01 +01:00
shadows: themeType == AppThemeType.doodle
? [
// EFFETTO RILIEVO (Luce in alto a sx, ombra in basso a dx)
const Shadow(color: Colors.white, offset: Offset(-1.5, -1.5), blurRadius: 1),
Shadow(color: Colors.black.withOpacity(0.25), offset: const Offset(1.5, 1.5), blurRadius: 2),
]
: [Shadow(color: Colors.black.withOpacity(0.3), offset: const Offset(1, 2), blurRadius: 2)]
))
2026-02-27 23:35:54 +01:00
),
2026-03-14 19:00:00 +01:00
const SizedBox(height: 8),
// --- ROW DEI PULSANTI AGGIORNATA ---
Row(
mainAxisSize: MainAxisSize.min,
children: [
// TASTO AUDIO CON CONTORNO
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
AudioService.instance.toggleMute();
});
},
child: Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: themeType == AppThemeType.doodle ? Colors.transparent : theme.text.withOpacity(0.05),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: themeType == AppThemeType.doodle ? const Color(0xFF111122) : theme.text.withOpacity(0.3), width: 1.5),
),
child: Icon(
isMuted ? Icons.volume_off : Icons.volume_up,
color: themeType == AppThemeType.doodle ? const Color(0xFF111122) : theme.text.withOpacity(0.8),
size: 16
),
),
),
const SizedBox(width: 10),
// TASTO INFORMAZIONI (TUTORIAL) CON CONTORNO
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
showDialog(context: context, builder: (ctx) => const TutorialDialog());
},
child: Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: themeType == AppThemeType.doodle ? Colors.transparent : theme.text.withOpacity(0.05),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: themeType == AppThemeType.doodle ? const Color(0xFF111122) : theme.text.withOpacity(0.3), width: 1.5),
),
child: Icon(
Icons.info_outline,
color: themeType == AppThemeType.doodle ? const Color(0xFF111122) : theme.text.withOpacity(0.8),
size: 16
),
),
),
],
2026-02-27 23:35:54 +01:00
),
],
),
2026-03-13 23:00:01 +01:00
_PlayerScore(color: theme.playerBlue, score: blueScore, isTurn: !isRedTurn, textColor: theme.text, title: nameBlue, themeType: themeType),
2026-02-27 23:35:54 +01:00
],
),
);
}
}
class _PlayerScore extends StatelessWidget {
final Color color;
final int score;
final bool isTurn;
final Color textColor;
final String title;
2026-03-13 23:00:01 +01:00
final AppThemeType themeType;
2026-02-27 23:35:54 +01:00
2026-03-13 23:00:01 +01:00
const _PlayerScore({required this.color, required this.score, required this.isTurn, required this.textColor, required this.title, required this.themeType});
2026-02-27 23:35:54 +01:00
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
2026-03-13 23:00:01 +01:00
Text(title, style: _getTextStyle(themeType, TextStyle(fontWeight: FontWeight.bold, color: isTurn ? color : textColor.withOpacity(0.5), fontSize: 12))),
2026-02-27 23:35:54 +01:00
const SizedBox(height: 5),
AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 10),
decoration: BoxDecoration(
color: color.withOpacity(isTurn ? 1.0 : 0.2),
borderRadius: BorderRadius.circular(15),
border: isTurn ? Border.all(color: Colors.white.withOpacity(0.4), width: 2) : Border.all(color: Colors.transparent, width: 2),
boxShadow: isTurn ? [
BoxShadow(color: color.withOpacity(0.5), offset: const Offset(0, 4), blurRadius: 6)
] : [],
),
2026-03-13 23:00:01 +01:00
child: Text('$score', style: _getTextStyle(themeType, TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: isTurn ? Colors.white : textColor.withOpacity(0.5)))),
2026-02-27 23:35:54 +01:00
),
],
);
}
}