import 'package:battle/button/button_color.dart'; import 'package:battle/data/card.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../page/game/status_notifier_mixin.dart'; import '../utils/utils.dart'; enum ButtonState { start, stop } class ButtonInfo { Color color; int startIndex; int endIndex; double process; int pauseSecond; ButtonInfo({ required this.color, required this.startIndex, required this.endIndex, this.process = 0, this.pauseSecond = 0, }); } enum GameStatus { wait, running, end } /// 四步完成随机性 /// 1. 根据答案编排出按钮颜色的最终位置 /// 2. 随机生成初始位置数组并赋值给按钮 /// 3. 打乱按钮顺序即调整按钮的起始位置 /// 4. 随机生成按钮出发顺序并赋值给动画 class GameController with ChangeNotifier, StatusNotifierMixin { final CardItem cardItem; final TickerProvider vsync; GameController(this.cardItem, {required this.vsync}) { _generator = ButtonGenerator(cardItem); _animationController = AnimationController(upperBound: 6.0, vsync: vsync); _animationController.addListener(() { if (_animationController.value >= 6.0) { _status = GameStatus.end; } else { _generator.move(_animationController.value); } notifyListeners(status: _status); }); } late ButtonGenerator _generator; late AnimationController _animationController; GameStatus _status = GameStatus.wait; GameStatus get status => _status; List get buttonList => _generator.buttonList; int get count => (_animationController.value * _generator.totalDuration.inSeconds / 6).toInt(); bool get isRunning => _animationController.isAnimating; int get score => _generator.score; void stop(){ if (_animationController.isAnimating) { _animationController.stop(canceled: false); } } void startOrReset() { if (_animationController.isAnimating) { _animationController.reset(); } _generator.randomButton(); _animationController.duration = _generator.totalDuration; _status = GameStatus.running; _animationController.forward(from: 0); } @override void dispose() { _animationController.dispose(); super.dispose(); } } class ButtonGenerator { final CardItem cardItem; ButtonGenerator(this.cardItem); late List buttonList = []; final List _progressList = List.generate(6, (_) => 0.0); int score = 60; Duration get totalDuration { Duration base = Duration(seconds: cardItem.baseTime * buttonList.length); Duration extra = Duration(seconds: buttonList.fold(0, (p, e) => p + e.pauseSecond)); return base + extra; } void randomButton() { List startIndex = generateIntList(); buttonList = List.generate(6, (index) { final answer = cardItem.answer[index] - 1; return ButtonInfo( color: buttonColors[answer], startIndex: startIndex[index], endIndex: index, pauseSecond: generateExtraTime(cardItem.lowerTime, cardItem.upperTime), ); }); buttonList.shuffle(); buttonList[5].pauseSecond = 0; var swap = checkNeedSwap(); if (swap.$1 && swap.$2 != swap.$3) { int be1 = buttonList[swap.$2].endIndex; int be2 = buttonList[swap.$3].endIndex; buttonList[swap.$2].endIndex = be2; buttonList[swap.$3].endIndex = be1; score = 40; } else { score = 60; } int totalSeconds = totalDuration.inSeconds; for (int i = 0; i < 6; i++) { _progressList[i] = 0; } print("-------------------------------------"); for (int i = 0; i < 6; i++) { final button = buttonList[i]; double value = (button.pauseSecond + cardItem.baseTime) / totalSeconds * 6; for (int j = i; j < 6; j++) { _progressList[j] = (value + _progressList[j]); } print("progress:${_progressList.map((i) => i.toStringAsFixed(2))}"); } print("-------------------------------------"); } void move(final double progress) { int index = 0; double lastProgress = 0; for (int i = 0; i < 6; i++) { if (_progressList[i] > progress) { index = i; break; } lastProgress = _progressList[i]; buttonList[index].process = 1.0; } final button = buttonList[index]; final pauseProgress = button.pauseSecond / (button.pauseSecond + cardItem.baseTime); // print("${progress},${progress - lastProgress},${pauseProgress}"); if (progress - lastProgress >= pauseProgress) { button.process = ((progress - lastProgress - pauseProgress) / (_progressList[index] - lastProgress - pauseProgress)) .clamp(0.0, 1.0); } } }