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

Flutter随机灯光变色、状态记录与按键验证实现问题咨询

解决方案:实现随机亮灯与按键验证功能

核心问题分析

  1. randomLights方法数组越界错误:直接对空数组ans使用下标赋值会触发异常,需先添加元素。
  2. 未维护亮灯状态:状态类中未保存选中灯光ID和对应颜色,无法驱动UI更新。
  3. 全局变量滥用:计时器等全局变量易导致状态混乱,应移至状态类内部。
  4. 重复代码冗余:8个按钮与灯光组件代码重复,可通过循环生成简化。
  5. 按键验证逻辑缺失:未判断玩家点击的按钮是否对应亮灯。

修改后的完整代码

import 'dart:math';
import 'package:flutter/material.dart';
import 'globals.dart' as globals;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const LBulb(),
    );
  }
}

class LBulb extends StatefulWidget {
  const LBulb({super.key});

  @override
  State<LBulb> createState() => _LBulbState();
}

class _LBulbState extends State<LBulb> {
  final Stopwatch _stopwatchD = Stopwatch();
  final Stopwatch _stopwatchR = Stopwatch();
  int _gameVersion = 0;
  List<int> _selectedLights = [];
  List<Color> _lightColors = List.filled(8, Colors.white);

  @override
  void initState() {
    _gameVersion = _oneOrThree();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.blue[600]?.withOpacity(0.5),
      ),
      body: Container(
        decoration: const BoxDecoration(
          image: DecorationImage(
              image: AssetImage("assets/images/background2.png"),
              fit: BoxFit.cover),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const SizedBox(height: 60),
            const Text(
              "请点击对应亮灯的按钮",
              textAlign: TextAlign.center,
              style: TextStyle(
                  color: Colors.black,
                  fontSize: 40,
                  fontWeight: FontWeight.bold,
                  fontFamily: 'Alkatra'),
            ),
            const SizedBox(height: 30),
            Center(
              child: Container(
                height: 500,
                width: 810,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(100),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.5),
                      offset: const Offset(7.0, 7.0),
                      blurRadius: 10.0,
                    ),
                  ],
                ),
                child: screenBuilding(
                  distance: 310.0,
                  // 主按钮
                  centerButton: GestureDetector(
                    onTapDown: (details) {
                      _stopwatchD.start();
                      // 随机选灯并更新颜色
                      setState(() {
                        _selectedLights = _randomLights(_gameVersion);
                        _lightColors = List.filled(8, Colors.white);
                        for (int lightId in _selectedLights) {
                          _lightColors[lightId - 1] = Colors.green;
                        }
                      });
                    },
                    onTapUp: (details) {
                      _stopwatchD.stop();
                      globals.detectionTime = _stopwatchD.elapsed;
                      globals.detectionTimes[globals.numOfTurn] = globals.detectionTime;
                      _stopwatchD.reset();
                      globals.detectionTime = const Duration(seconds: 0);
                      globals.numOfTurn++;
                      print(globals.detectionTimes);
                      _stopwatchR.start();
                    },
                    child: Container(
                      height: 20,
                      width: 20,
                      decoration: const BoxDecoration(
                          color: Colors.black,
                          borderRadius: BorderRadius.circular(500)),
                    ),
                  ),
                  // 灯光对应的按钮
                  buttonsFirstRow: List.generate(8, (index) {
                    int lightId = index + 1;
                    return TextButton(
                      onPressed: () => _onLightButtonPressed(lightId),
                      child: Container(
                        height: 20,
                        width: 20,
                        decoration: const BoxDecoration(
                            color: Colors.black,
                            borderRadius: BorderRadius.circular(500)),
                      ),
                    );
                  }),
                  // 第一组4个灯光
                  buttonsSecondRowHalf1: List.generate(4, (index) {
                    int lightId = index + 1;
                    return TextButton(
                      onPressed: () => _onLightButtonPressed(lightId),
                      child: Container(
                        height: 20,
                        width: 20,
                        decoration: BoxDecoration(
                            color: _lightColors[index],
                            borderRadius: BorderRadius.circular(500),
                            border: Border.all(width: 3)),
                      ),
                    );
                  }),
                  // 第二组4个灯光
                  buttonsSecondRowHalf2: List.generate(4, (index) {
                    int lightId = index + 5;
                    return TextButton(
                      onPressed: () => _onLightButtonPressed(lightId),
                      child: Container(
                        height: 20,
                        width: 20,
                        decoration: BoxDecoration(
                            color: _lightColors[index + 4],
                            borderRadius: BorderRadius.circular(500),
                            border: Border.all(width: 3)),
                      ),
                    );
                  }),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  void _onLightButtonPressed(int lightId) {
    if (_selectedLights.contains(lightId)) {
      // 正确按键,停止响应计时器
      _stopwatchR.stop();
      globals.responseTime = _stopwatchR.elapsed;
      globals.responseTimes[globals.numOfTurn - 1] = globals.responseTime;
      _stopwatchR.reset();
      print("按键正确!响应时间: ${globals.responseTime}");
      
      // 重置状态,准备下一轮
      setState(() {
        _lightColors = List.filled(8, Colors.white);
        _selectedLights.clear();
        _gameVersion = _oneOrThree();
      });
    } else {
      print("按键错误,请点击亮灯对应的按钮");
    }
  }

  int _oneOrThree() {
    final rand = Random();
    return [1, 3][rand.nextInt(2)];
  }

  List<int> _randomLights(int version) {
    final rand = Random();
    List<int> availableLights = List.generate(8, (index) => index + 1);
    List<int> selected = [];
    
    if (version == 1) {
      selected.add(availableLights[rand.nextInt(availableLights.length)]);
    } else {
      for (int i = 0; i < 3; i++) {
        int randomIndex = rand.nextInt(availableLights.length);
        selected.add(availableLights[randomIndex]);
        availableLights.removeAt(randomIndex);
      }
    }
    return selected;
  }
}

关键修改说明

  • 状态管理优化:将计时器、选中灯光、灯光颜色移至状态类内部,避免全局变量状态混乱。
  • 修复随机选灯方法:通过add和removeAt操作数组,解决空数组下标赋值异常。
  • 动态生成组件:用List.generate循环生成按钮与灯光组件,减少重复代码。
  • 按键验证逻辑:判断点击的按钮ID是否在选中列表中,正确则停止计时器并重置状态,错误则提示。
  • UI实时更新:主按钮按下时通过setState更新灯光颜色,确保UI同步刷新。

内容的提问来源于stack exchange,提问作者מאי כהן

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:22:07