You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 17:20:27