|
@@ -1,8 +1,9 @@
|
|
|
import 'package:battle/button/button_color.dart';
|
|
|
import 'package:battle/data/card.dart';
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
-import 'package:widget/widget.dart';
|
|
|
+import 'package:flutter/material.dart';
|
|
|
|
|
|
+import '../page/game/status_notifier_mixin.dart';
|
|
|
import '../utils/utils.dart';
|
|
|
|
|
|
enum ButtonState { start, stop }
|
|
@@ -13,65 +14,100 @@ class ButtonInfo {
|
|
|
int endIndex;
|
|
|
double process;
|
|
|
|
|
|
- /// 是否执行超出回退动画
|
|
|
- bool overflow;
|
|
|
-
|
|
|
- /// 是否执行卡住动画
|
|
|
- bool pauseBottom;
|
|
|
-
|
|
|
- bool pauseInline;
|
|
|
-
|
|
|
- bool pauseRight;
|
|
|
-
|
|
|
- List<PathOp> ops;
|
|
|
+ int pauseSecond;
|
|
|
|
|
|
ButtonInfo({
|
|
|
required this.color,
|
|
|
required this.startIndex,
|
|
|
required this.endIndex,
|
|
|
this.process = 0,
|
|
|
- this.overflow = false,
|
|
|
- this.pauseBottom = false,
|
|
|
- this.pauseInline = false,
|
|
|
- this.pauseRight = false,
|
|
|
- this.ops = const [],
|
|
|
+ this.pauseSecond = 0,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+enum GameStatus { wait, running, end }
|
|
|
+
|
|
|
/// 四步完成随机性
|
|
|
/// 1. 根据答案编排出按钮颜色的最终位置
|
|
|
/// 2. 随机生成初始位置数组并赋值给按钮
|
|
|
/// 3. 打乱按钮顺序即调整按钮的起始位置
|
|
|
/// 4. 随机生成按钮出发顺序并赋值给动画
|
|
|
-class ButtonController with ChangeNotifier {
|
|
|
+class GameController with ChangeNotifier, StatusNotifierMixin<GameStatus> {
|
|
|
final CardItem cardItem;
|
|
|
- final TickerProvider vsync;
|
|
|
|
|
|
- ButtonController(this.cardItem, {required this.vsync}) {
|
|
|
- _animationController = AnimationController(
|
|
|
- upperBound: 6.0,
|
|
|
- vsync: vsync,
|
|
|
- duration: const Duration(seconds: 30),
|
|
|
- );
|
|
|
+ final TickerProvider vsync;
|
|
|
|
|
|
- _randomButton();
|
|
|
+ GameController(this.cardItem, {required this.vsync}) {
|
|
|
+ _generator = ButtonGenerator(cardItem);
|
|
|
+ _animationController = AnimationController(upperBound: 6.0, vsync: vsync);
|
|
|
|
|
|
_animationController.addListener(() {
|
|
|
- int index = _animationController.value ~/ 1;
|
|
|
- if (index == 6) return;
|
|
|
- double process = _animationController.value % 1.0;
|
|
|
+ if (_animationController.value >= 6.0) {
|
|
|
+ _status = GameStatus.end;
|
|
|
+ } else {
|
|
|
+ _generator.move(_animationController.value);
|
|
|
+ }
|
|
|
|
|
|
- buttonList[_moveIndex[index]].process = Curves.easeInOutQuint.transform(process);
|
|
|
- notifyListeners();
|
|
|
+ notifyListeners(status: _status);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ late ButtonGenerator _generator;
|
|
|
+
|
|
|
late AnimationController _animationController;
|
|
|
+
|
|
|
+ GameStatus _status = GameStatus.wait;
|
|
|
+
|
|
|
+ GameStatus get status => _status;
|
|
|
+
|
|
|
+ List<ButtonInfo> 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<ButtonInfo> buttonList = [];
|
|
|
- late List<int> _moveIndex = [];
|
|
|
+ final List<double> _progressList = List<double>.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() {
|
|
|
- _moveIndex = generateIntList();
|
|
|
+ void randomButton() {
|
|
|
List<int> startIndex = generateIntList();
|
|
|
|
|
|
buttonList = List.generate(6, (index) {
|
|
@@ -81,20 +117,67 @@ class ButtonController with ChangeNotifier {
|
|
|
color: buttonColors[answer],
|
|
|
startIndex: startIndex[index],
|
|
|
endIndex: index,
|
|
|
+ pauseSecond: generateExtraTime(cardItem.lowerTime, cardItem.upperTime),
|
|
|
);
|
|
|
});
|
|
|
- }
|
|
|
|
|
|
- bool get isRunning => _animationController.isAnimating;
|
|
|
+ buttonList.shuffle();
|
|
|
+ buttonList[5].pauseSecond = 0;
|
|
|
|
|
|
- void startOrReset() {
|
|
|
- if (_animationController.isAnimating) {
|
|
|
- _randomButton();
|
|
|
+ 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;
|
|
|
}
|
|
|
- _animationController.forward(from: 0);
|
|
|
+
|
|
|
+ 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 stop() {
|
|
|
- _animationController.stop();
|
|
|
+ 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];
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
}
|
|
|
}
|