Flutter猜字游戏实现胜利时终止游戏并显示祝贺弹窗
Flutter Hangman游戏:实现胜利判定与弹窗提示
要实现玩家获胜时终止游戏并弹出祝贺提示,核心是判断目标单词的所有字符是否都被玩家选中,复用现有弹窗逻辑处理胜利场景即可。以下是具体修改方案:
核心修改步骤
1. 添加胜利条件判断
将目标单词拆分为字符集合,对比玩家已选字符集合,若已选字符包含目标单词的所有字符,则判定胜利。
2. 实现胜利弹窗与重置
胜利弹窗逻辑和失败弹窗一致,仅提示内容不同,重置逻辑可复用失败时的状态重置代码。
3. 防止重复触发弹窗
新增状态标记游戏是否结束,阻止游戏结束后再次触发弹窗或操作按钮。
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:hangman/components/colors.dart'; import 'package:hangman/components/text_format.dart'; import 'package:hangman/models/game.dart'; import 'package:hangman/widget/figure_image.dart'; import 'package:hangman/widget/letter.dart'; import 'package:rflutter_alert/rflutter_alert.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { String word = 'ICARUS'; List<String> alphabets = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ]; // 标记游戏是否结束,防止重复弹窗 bool _isGameOver = false; // 检查是否获胜:已选字符覆盖目标单词所有字符 bool _checkWin() { Set<String> targetChars = word.split('').toSet(); Set<String> selectedChars = Game.selectedChar.toSet(); return selectedChars.containsAll(targetChars); } // 统一重置游戏状态 void _resetGame() { setState(() { Game.tries = 0; Game.selectedChar.clear(); _isGameOver = false; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: primaryColor, appBar: AppBar( title: const PoppinsText( text: "Hangman", fontS: 24, fontWeight: FontWeight.w600, ), centerTitle: true, elevation: 0, backgroundColor: primaryColor, ), body: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ const Divider(color: Colors.black), Center( child: Stack( children: [ figureImage(Game.tries >= 0, 'assets/hang.png'), figureImage(Game.tries >= 1, 'assets/head.png'), figureImage(Game.tries >= 2, 'assets/body.png'), figureImage(Game.tries >= 3, 'assets/ra.png'), figureImage(Game.tries >= 4, 'assets/la.png'), figureImage(Game.tries >= 5, 'assets/rl.png'), figureImage(Game.tries >= 6, 'assets/ll.png'), ], ), ), Padding( padding: const EdgeInsets.all(12.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: word.split('').map((e) => letter( e.toUpperCase(), !Game.selectedChar.contains(e.toUpperCase()) )).toList(), ), ), SizedBox( width: double.infinity, height: 350.0, child: GridView.count( crossAxisCount: 7, mainAxisSpacing: 8.0, crossAxisSpacing: 8.0, padding: const EdgeInsets.all(25.0), children: alphabets.map((e) { return RawMaterialButton( // 游戏结束或字符已选则禁用按钮 onPressed: (_isGameOver || Game.selectedChar.contains(e)) ? null : () { setState(() { Game.selectedChar.add(e); if (!word.split('').contains(e)) { Game.tries++; } // 检查失败条件 if (Game.tries == 6) { _isGameOver = true; Alert( context: context, type: AlertType.error, title: "失败!", desc: "你把那个家伙吊死了...", buttons: [ DialogButton( onPressed: () { Navigator.pop(context); _resetGame(); }, width: 120, child: const Text( "再来一局", style: TextStyle(color: Colors.white, fontSize: 20), ), ) ], ).show(); } // 检查胜利条件 else if (_checkWin()) { _isGameOver = true; Alert( context: context, type: AlertType.success, title: "恭喜!", desc: "你成功救下了他!", buttons: [ DialogButton( onPressed: () { Navigator.pop(context); _resetGame(); }, width: 120, child: const Text( "再来一局", style: TextStyle(color: Colors.white, fontSize: 20), ), ) ], ).show(); } }); }, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(4), ), fillColor: Game.selectedChar.contains(e) ? Colors.black87 : primaryDark, child: PoppinsText( text: e, fontS: 24, color: Colors.white, fontWeight: FontWeight.w700, ), ); }).toList(), ), ), ], ), ); } }
关键修改说明
- 新增
_isGameOver状态,避免游戏结束后重复触发弹窗或操作 - 新增
_checkWin()方法,通过集合对比高效判断是否猜中所有字符 - 在字符选择回调中新增胜利条件判断,触发对应弹窗
- 提取
_resetGame()方法统一处理重置逻辑,减少代码冗余
内容的提问来源于stack exchange,提问作者Icarus
相关产品推荐
相关产品推荐

