import 'package:flutter/material.dart'; import 'package:aesthetica_wallpaper/models/puzzle_game_interface.dart'; import 'package:confetti/confetti.dart'; /// 拼图完成页面 class PuzzleCompleteScreen extends StatefulWidget { final IPuzzleGame game; const PuzzleCompleteScreen({super.key, required this.game}); @override State createState() => _PuzzleCompleteScreenState(); } class _PuzzleCompleteScreenState extends State with SingleTickerProviderStateMixin { late ConfettiController _confettiController; late AnimationController _animationController; late Animation _scaleAnimation; late Animation _fadeAnimation; @override void initState() { super.initState(); _confettiController = ConfettiController( duration: const Duration(seconds: 3), ); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 800), ); _scaleAnimation = CurvedAnimation( parent: _animationController, curve: Curves.elasticOut, ); _fadeAnimation = CurvedAnimation( parent: _animationController, curve: Curves.easeIn, ); // 启动动画和彩带 _animationController.forward(); _confettiController.play(); } @override void dispose() { _confettiController.dispose(); _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final stars = widget.game.getStarRating(); return Scaffold( body: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Colors.purple.shade400, Colors.blue.shade400], ), ), child: SafeArea( child: Stack( children: [ // 彩带效果 Align( alignment: Alignment.topCenter, child: ConfettiWidget( confettiController: _confettiController, blastDirectionality: BlastDirectionality.explosive, particleDrag: 0.05, emissionFrequency: 0.05, numberOfParticles: 50, gravity: 0.1, shouldLoop: false, colors: const [ Colors.green, Colors.blue, Colors.pink, Colors.orange, Colors.purple, ], ), ), // 主要内容 Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 完成图标 ScaleTransition( scale: _scaleAnimation, child: Container( padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.white, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.2), blurRadius: 20, offset: const Offset(0, 10), ), ], ), child: const Icon( Icons.check_circle, size: 80, color: Colors.green, ), ), ), const SizedBox(height: 32), // 标题 FadeTransition( opacity: _fadeAnimation, child: const Text( '🎉 Congratulations!', style: TextStyle( fontSize: 36, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), const SizedBox(height: 24), // 星级评分 _buildStarRating(stars), const SizedBox(height: 32), // 成绩卡片 _buildScoreCard(), const SizedBox(height: 32), // 奖励信息 _buildRewards(), const SizedBox(height: 32), // 操作按钮 _buildActionButtons(), ], ), ), ), ], ), ), ), ); } Widget _buildStarRating(int stars) { return FadeTransition( opacity: _fadeAnimation, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(3, (index) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: Icon( index < stars ? Icons.star : Icons.star_border, size: 48, color: Colors.amber, ), ); }), ), ); } Widget _buildScoreCard() { return FadeTransition( opacity: _fadeAnimation, child: Container( padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 20, offset: const Offset(0, 10), ), ], ), child: Column( children: [ const Text( 'Game Stats', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.purple, ), ), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildScoreItem( Icons.timer, 'Time', _formatDuration(widget.game.elapsedTime), Colors.blue, ), _buildScoreItem( Icons.directions_walk, 'Moves', '${widget.game.moves}', Colors.orange, ), ], ), const SizedBox(height: 16), const Divider(), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildScoreItem( Icons.grid_4x4, 'Difficulty', widget.game.difficultyLabel, Colors.purple, ), _buildScoreItem( Icons.emoji_events, 'Best Record', '--:--', Colors.green, ), ], ), ], ), ), ); } Widget _buildScoreItem( IconData icon, String label, String value, Color color, ) { return Column( children: [ Icon(icon, color: color, size: 32), const SizedBox(height: 8), Text( value, style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: color, ), ), const SizedBox(height: 4), Text( label, style: TextStyle(fontSize: 12, color: Colors.grey.shade600), ), ], ); } Widget _buildRewards() { return FadeTransition( opacity: _fadeAnimation, child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(16), border: Border.all( color: Colors.white.withValues(alpha: 0.3), width: 2, ), ), child: Column( children: [ const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.card_giftcard, color: Colors.white), SizedBox(width: 8), Text( 'Rewards', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ), ), ], ), const SizedBox(height: 16), _buildRewardItem(Icons.stars, '+ 50 Points'), const SizedBox(height: 8), _buildRewardItem( Icons.wallpaper, 'Unlocked "${widget.game.difficultyLabel} Challenge" Wallpaper', ), if (widget.game.getStarRating() == 3) ...[ const SizedBox(height: 8), _buildRewardItem(Icons.emoji_events, '3-Star Achievement!'), ], ], ), ), ); } Widget _buildRewardItem(IconData icon, String text) { return Row( children: [ Icon(icon, color: Colors.amber, size: 20), const SizedBox(width: 8), Expanded( child: Text( text, style: const TextStyle(color: Colors.white, fontSize: 14), ), ), ], ); } Widget _buildActionButtons() { return FadeTransition( opacity: _fadeAnimation, child: Column( children: [ // 再玩一次 SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () { Navigator.pop(context); // 返回游戏页面 Navigator.pop(context); // 返回菜单页面 }, style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.purple, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.refresh), SizedBox(width: 8), Text( 'Play Again', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ], ), ), ), const SizedBox(height: 12), // 返回首页 TextButton( onPressed: () { Navigator.popUntil(context, (route) => route.isFirst); }, child: const Text( 'Back to Home', style: TextStyle(color: Colors.white, fontSize: 16), ), ), ], ), ); } String _formatDuration(Duration duration) { final minutes = duration.inMinutes.toString().padLeft(2, '0'); final seconds = (duration.inSeconds % 60).toString().padLeft(2, '0'); return '$minutes:$seconds'; } }