button_controller.dart 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import 'package:battle/button/button_color.dart';
  2. import 'package:battle/data/card.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import '../page/game/status_notifier_mixin.dart';
  6. import '../utils/utils.dart';
  7. enum ButtonState { start, stop }
  8. class ButtonInfo {
  9. Color color;
  10. int startIndex;
  11. int endIndex;
  12. double process;
  13. int pauseSecond;
  14. ButtonInfo({
  15. required this.color,
  16. required this.startIndex,
  17. required this.endIndex,
  18. this.process = 0,
  19. this.pauseSecond = 0,
  20. });
  21. }
  22. enum GameStatus { wait, running, end }
  23. /// 四步完成随机性
  24. /// 1. 根据答案编排出按钮颜色的最终位置
  25. /// 2. 随机生成初始位置数组并赋值给按钮
  26. /// 3. 打乱按钮顺序即调整按钮的起始位置
  27. /// 4. 随机生成按钮出发顺序并赋值给动画
  28. class GameController with ChangeNotifier, StatusNotifierMixin<GameStatus> {
  29. final CardItem cardItem;
  30. final TickerProvider vsync;
  31. GameController(this.cardItem, {required this.vsync}) {
  32. _generator = ButtonGenerator(cardItem);
  33. _animationController = AnimationController(upperBound: 6.0, vsync: vsync);
  34. _animationController.addListener(() {
  35. if (_animationController.value >= 6.0) {
  36. _status = GameStatus.end;
  37. } else {
  38. _generator.move(_animationController.value);
  39. }
  40. notifyListeners(status: _status);
  41. });
  42. }
  43. late ButtonGenerator _generator;
  44. late AnimationController _animationController;
  45. GameStatus _status = GameStatus.wait;
  46. GameStatus get status => _status;
  47. List<ButtonInfo> get buttonList => _generator.buttonList;
  48. int get count => (_animationController.value * _generator.totalDuration.inSeconds / 6).toInt();
  49. bool get isRunning => _animationController.isAnimating;
  50. int get score => _generator.score;
  51. void stop(){
  52. if (_animationController.isAnimating) {
  53. _animationController.stop(canceled: false);
  54. }
  55. }
  56. void startOrReset() {
  57. if (_animationController.isAnimating) {
  58. _animationController.reset();
  59. }
  60. _generator.randomButton();
  61. _animationController.duration = _generator.totalDuration;
  62. _status = GameStatus.running;
  63. _animationController.forward(from: 0);
  64. }
  65. @override
  66. void dispose() {
  67. _animationController.dispose();
  68. super.dispose();
  69. }
  70. }
  71. class ButtonGenerator {
  72. final CardItem cardItem;
  73. ButtonGenerator(this.cardItem);
  74. late List<ButtonInfo> buttonList = [];
  75. final List<double> _progressList = List<double>.generate(6, (_) => 0.0);
  76. int score = 60;
  77. Duration get totalDuration {
  78. Duration base = Duration(seconds: cardItem.baseTime * buttonList.length);
  79. Duration extra = Duration(seconds: buttonList.fold(0, (p, e) => p + e.pauseSecond));
  80. return base + extra;
  81. }
  82. void randomButton() {
  83. List<int> startIndex = generateIntList();
  84. buttonList = List.generate(6, (index) {
  85. final answer = cardItem.answer[index] - 1;
  86. return ButtonInfo(
  87. color: buttonColors[answer],
  88. startIndex: startIndex[index],
  89. endIndex: index,
  90. pauseSecond: generateExtraTime(cardItem.lowerTime, cardItem.upperTime),
  91. );
  92. });
  93. buttonList.shuffle();
  94. buttonList[5].pauseSecond = 0;
  95. var swap = checkNeedSwap();
  96. if (swap.$1 && swap.$2 != swap.$3) {
  97. int be1 = buttonList[swap.$2].endIndex;
  98. int be2 = buttonList[swap.$3].endIndex;
  99. buttonList[swap.$2].endIndex = be2;
  100. buttonList[swap.$3].endIndex = be1;
  101. score = 40;
  102. } else {
  103. score = 60;
  104. }
  105. int totalSeconds = totalDuration.inSeconds;
  106. for (int i = 0; i < 6; i++) {
  107. _progressList[i] = 0;
  108. }
  109. print("-------------------------------------");
  110. for (int i = 0; i < 6; i++) {
  111. final button = buttonList[i];
  112. double value = (button.pauseSecond + cardItem.baseTime) / totalSeconds * 6;
  113. for (int j = i; j < 6; j++) {
  114. _progressList[j] = (value + _progressList[j]);
  115. }
  116. print("progress:${_progressList.map((i) => i.toStringAsFixed(2))}");
  117. }
  118. print("-------------------------------------");
  119. }
  120. void move(final double progress) {
  121. int index = 0;
  122. double lastProgress = 0;
  123. for (int i = 0; i < 6; i++) {
  124. if (_progressList[i] > progress) {
  125. index = i;
  126. break;
  127. }
  128. lastProgress = _progressList[i];
  129. buttonList[index].process = 1.0;
  130. }
  131. final button = buttonList[index];
  132. final pauseProgress = button.pauseSecond / (button.pauseSecond + cardItem.baseTime);
  133. // print("${progress},${progress - lastProgress},${pauseProgress}");
  134. if (progress - lastProgress >= pauseProgress) {
  135. button.process =
  136. ((progress - lastProgress - pauseProgress) / (_progressList[index] - lastProgress - pauseProgress))
  137. .clamp(0.0, 1.0);
  138. }
  139. }
  140. }