From 9e4f29caed81d953480c20d9373916e6f427ae84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Mon, 6 Sep 2021 17:07:59 +0200
Subject: [PATCH] Add board animations

---
 android/gradle.properties                     |  4 +-
 .../metadata/android/en-US/changelogs/45.txt  |  1 +
 .../metadata/android/fr-FR/changelogs/45.txt  |  1 +
 lib/entities/cell.dart                        |  9 ++
 lib/layout/game.dart                          |  8 +-
 lib/provider/data.dart                        | 25 ++++++
 lib/utils/board_animate.dart                  | 85 +++++++++++++++++++
 lib/utils/game_utils.dart                     |  2 +
 8 files changed, 132 insertions(+), 3 deletions(-)
 create mode 100644 fastlane/metadata/android/en-US/changelogs/45.txt
 create mode 100644 fastlane/metadata/android/fr-FR/changelogs/45.txt
 create mode 100644 lib/utils/board_animate.dart

diff --git a/android/gradle.properties b/android/gradle.properties
index 7e6b4cd..d6af5de 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
 android.useAndroidX=true
 android.enableJetifier=true
-app.versionName=0.0.44
-app.versionCode=44
+app.versionName=0.0.45
+app.versionCode=45
diff --git a/fastlane/metadata/android/en-US/changelogs/45.txt b/fastlane/metadata/android/en-US/changelogs/45.txt
new file mode 100644
index 0000000..dbd9e10
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/45.txt
@@ -0,0 +1 @@
+Add board animations (start game and win)
diff --git a/fastlane/metadata/android/fr-FR/changelogs/45.txt b/fastlane/metadata/android/fr-FR/changelogs/45.txt
new file mode 100644
index 0000000..f29cf07
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/45.txt
@@ -0,0 +1 @@
+Ajout d'animations sur le plateau (début de partie et victoire)
diff --git a/lib/entities/cell.dart b/lib/entities/cell.dart
index 080a535..78b448f 100644
--- a/lib/entities/cell.dart
+++ b/lib/entities/cell.dart
@@ -7,6 +7,7 @@ class Cell {
   int value;
   bool isFixed;
   int conflictsCount = 0;
+  bool isAnimated = false;
 
   Cell(
     @required this.value,
@@ -84,6 +85,14 @@ class Cell {
       }
     }
 
+    if (this.isAnimated) {
+      if (this.isFixed) {
+        backgroundColor = Colors.green[300];
+      } else {
+        backgroundColor = Colors.green[200];
+      }
+    }
+
     return backgroundColor;
   }
 
diff --git a/lib/layout/game.dart b/lib/layout/game.dart
index dc59397..67c8177 100644
--- a/lib/layout/game.dart
+++ b/lib/layout/game.dart
@@ -5,12 +5,18 @@ import 'package:flutter/material.dart';
 import '../entities/cell.dart';
 import '../layout/board.dart';
 import '../provider/data.dart';
+import '../utils/board_animate.dart';
 import '../utils/board_utils.dart';
 import '../utils/game_utils.dart';
 
 class Game {
 
   static Container buildGameWidget(Data myProvider) {
+    bool gameIsFinished = BoardUtils.checkBoardIsSolved(myProvider);
+    if (gameIsFinished) {
+      BoardAnimate.startAnimation(myProvider, 'win');
+    }
+
     return Container(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.start,
@@ -18,7 +24,7 @@ class Game {
         children: [
           Board.buildGameBoard(myProvider),
           SizedBox(height: 2),
-          BoardUtils.checkBoardIsSolved(myProvider) ? Game.buildWinMessage(myProvider) : Game.buildSelectCellValueBar(myProvider),
+          gameIsFinished ? Game.buildWinMessage(myProvider) : Game.buildSelectCellValueBar(myProvider),
         ],
       ),
     );
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
index 77e1bed..073682d 100644
--- a/lib/provider/data.dart
+++ b/lib/provider/data.dart
@@ -32,6 +32,7 @@ class Data extends ChangeNotifier {
   int _currentCellRow = null;
   int _currentCellValue = null;
   int _givenTipsCount = 0;
+  bool _animationInProgress = false;
   List _shuffledCellValues = [];
 
   String get level => _level;
@@ -182,4 +183,28 @@ class Data extends ChangeNotifier {
     _stateRunning = stateRunning;
     notifyListeners();
   }
+
+  bool get animationInProgress => _animationInProgress;
+  void updateAnimationInProgress(bool animationInProgress) {
+    _animationInProgress = animationInProgress;
+    notifyListeners();
+  }
+
+  void setAnimatedBackground(List animatedCellsPattern) {
+    int boardSideLength = _blockSizeHorizontal * _blockSizeVertical;
+    for (var row = 0; row < boardSideLength; row++) {
+      for (var col = 0; col < boardSideLength; col++) {
+        _cells[row][col].isAnimated = animatedCellsPattern[row][col];
+      }
+    }
+    notifyListeners();
+  }
+  void resetAnimatedBackground() {
+    int boardSideLength = _blockSizeHorizontal * _blockSizeVertical;
+    for (var row = 0; row < boardSideLength; row++) {
+      for (var col = 0; col < boardSideLength; col++) {
+        _cells[row][col].isAnimated = false;
+      }
+    }
+  }
 }
diff --git a/lib/utils/board_animate.dart b/lib/utils/board_animate.dart
new file mode 100644
index 0000000..e328a0e
--- /dev/null
+++ b/lib/utils/board_animate.dart
@@ -0,0 +1,85 @@
+import 'dart:async';
+import 'dart:math';
+
+import '../entities/cell.dart';
+import '../provider/data.dart';
+
+class BoardAnimate {
+
+  // Start game animation: blinking tiles
+  static List createStartGameAnimationPatterns(Data myProvider) {
+    List<List> patterns = [];
+
+    int patternsCount = 3;
+    int boardSideLength = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
+
+    for (var patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
+      List<List> pattern = [];
+      for (var row = 0; row < boardSideLength; row++) {
+        List<bool> patternRow = [];
+        for (var col = 0; col < boardSideLength; col++) {
+          patternRow.add(((patternIndex + row + col) % 2 == 0));
+        }
+        pattern.add(patternRow);
+      }
+      patterns.add(pattern);
+    }
+
+    return patterns;
+  }
+
+  // Win game animation: fill board with colored rows, from bottom to top
+  static List createWinGameAnimationPatterns(Data myProvider) {
+    List<List> patterns = [];
+
+    int boardSideLength = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
+    int patternsCount = boardSideLength + 6;
+
+    for (var patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
+      List<List> pattern = [];
+      for (var row = 0; row < boardSideLength; row++) {
+        List<bool> patternRow = [];
+        for (var col = 0; col < boardSideLength; col++) {
+          patternRow.add(row > (patternIndex - 3));
+        }
+        pattern.add(patternRow);
+      }
+      patterns.add(pattern);
+    }
+
+    return patterns;
+  }
+
+  static void startAnimation(Data myProvider, String animationType) {
+    List patterns = [];
+
+    switch(animationType) {
+      case 'start':
+        patterns = createStartGameAnimationPatterns(myProvider);
+        break;
+      case 'win':
+        patterns = createWinGameAnimationPatterns(myProvider);
+        break;
+    }
+
+    int _patternIndex = patterns.length;
+
+    myProvider.updateAnimationInProgress(true);
+
+    Timer _timerAnimateBoard;
+    const interval = const Duration(milliseconds: 200);
+    _timerAnimateBoard = new Timer.periodic(
+      interval,
+      (Timer timer) {
+        if (_patternIndex == 0) {
+          timer.cancel();
+          myProvider.resetAnimatedBackground();
+          myProvider.updateAnimationInProgress(false);
+        } else {
+          _patternIndex--;
+          myProvider.setAnimatedBackground(patterns[_patternIndex]);
+        }
+      },
+    );
+  }
+}
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
index 508c3d6..51758ba 100644
--- a/lib/utils/game_utils.dart
+++ b/lib/utils/game_utils.dart
@@ -1,4 +1,5 @@
 import '../provider/data.dart';
+import '../utils/board_animate.dart';
 import '../utils/board_utils.dart';
 import '../utils/game_utils.dart';
 
@@ -15,6 +16,7 @@ class GameUtils {
     myProvider.shuffleCellValues();
     myProvider.updateCells = BoardUtils.createEmptyBoard(myProvider.blockSizeHorizontal * myProvider.blockSizeVertical);
     BoardUtils.pickGrid(myProvider);
+    BoardAnimate.startAnimation(myProvider, 'start');
   }
 
   static void showTip(Data myProvider) {
-- 
GitLab