From 56d02932ce0849276f479b7db2d8bc3f2b21a030 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Wed, 18 Aug 2021 16:10:23 +0200
Subject: [PATCH] Add animations

---
 android/gradle.properties                     |   4 +-
 .../metadata/android/en-US/changelogs/13.txt  |   1 +
 .../metadata/android/fr-FR/changelogs/13.txt  |   1 +
 lib/entities/cell.dart                        |   2 +-
 lib/utils/board_animate.dart                  | 111 +++++++++++++++++-
 lib/utils/game_utils.dart                     |   2 +
 6 files changed, 115 insertions(+), 6 deletions(-)
 create mode 100644 fastlane/metadata/android/en-US/changelogs/13.txt
 create mode 100644 fastlane/metadata/android/fr-FR/changelogs/13.txt

diff --git a/android/gradle.properties b/android/gradle.properties
index d9abd55..6638812 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.12
-app.versionCode=12
+app.versionName=0.0.13
+app.versionCode=13
diff --git a/fastlane/metadata/android/en-US/changelogs/13.txt b/fastlane/metadata/android/en-US/changelogs/13.txt
new file mode 100644
index 0000000..1627715
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/13.txt
@@ -0,0 +1 @@
+Add multiple animations (start game, win, fail)
diff --git a/fastlane/metadata/android/fr-FR/changelogs/13.txt b/fastlane/metadata/android/fr-FR/changelogs/13.txt
new file mode 100644
index 0000000..f997167
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/13.txt
@@ -0,0 +1 @@
+Ajout d'animations (début de partie, victoire, défaite)
diff --git a/lib/entities/cell.dart b/lib/entities/cell.dart
index 106091c..9bd32cc 100644
--- a/lib/entities/cell.dart
+++ b/lib/entities/cell.dart
@@ -50,7 +50,7 @@ class Cell {
             }
             if (BoardUtils.checkGameIsFinished(myProvider)) {
               myProvider.updateReportMode(false);
-              BoardAnimate.startAnimation(myProvider);
+              BoardAnimate.startAnimation(myProvider, myProvider.gameWin ? 'win' : 'fail');
             }
           }
         },
diff --git a/lib/utils/board_animate.dart b/lib/utils/board_animate.dart
index d4aae46..be41181 100644
--- a/lib/utils/board_animate.dart
+++ b/lib/utils/board_animate.dart
@@ -1,11 +1,101 @@
 import 'dart:async';
+import 'dart:math';
 
 import '../entities/cell.dart';
 import '../provider/data.dart';
 
 class BoardAnimate {
 
-  static List createPatterns(Data myProvider) {
+  // Start game animation: blinking tiles
+  static List createStartGameAnimationPatterns(Data myProvider) {
+    List<List> patterns = [];
+
+    int patternsCount = 4;
+    int sizeHorizontal = myProvider.sizeHorizontal;
+    int sizeVertical = myProvider.sizeVertical;
+
+    for (var patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
+      List<List> pattern = [];
+      for (var row = 0; row < sizeVertical; row++) {
+        List<bool> patternRow = [];
+        for (var col = 0; col < sizeHorizontal; col++) {
+          patternRow.add(((patternIndex + row + col) % 2 == 0));
+        }
+        pattern.add(patternRow);
+      }
+      patterns.add(pattern);
+    }
+
+    return patterns;
+  }
+
+  // Failed game animation: explosions blowing from exploded mines
+  static List createExplosionAnimationPatterns(Data myProvider) {
+    List<List> patterns = [];
+
+    int sizeHorizontal = myProvider.sizeHorizontal;
+    int sizeVertical = myProvider.sizeVertical;
+
+    List explodedMines = [];
+    for (var row = 0; row < sizeVertical; row++) {
+      for (var col = 0; col < sizeHorizontal; col++) {
+        if (myProvider.cells[row][col].isExploded) {
+          explodedMines.add([row, col]);
+        }
+      }
+    }
+    if (explodedMines.length == 0) {
+      explodedMines.add([(sizeVertical / 2).floor(), (sizeHorizontal / 2).floor()]);
+    }
+
+    int patternsCount = max(sizeHorizontal, sizeVertical);
+
+    for (var patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
+      List<List> pattern = [];
+      for (var row = 0; row < sizeVertical; row++) {
+        List<bool> patternRow = [];
+        for (var col = 0; col < sizeHorizontal; col++) {
+          bool isHilighted = false;
+          for (var mineIndex = 0; mineIndex < explodedMines.length; mineIndex++) {
+            double distance = sqrt(pow((explodedMines[mineIndex][0] - row), 2) + pow((explodedMines[mineIndex][1] - col), 2));
+            isHilighted = isHilighted || ((patternIndex + distance) % 3 < 1);
+          }
+          patternRow.add(isHilighted);
+        }
+        pattern.add(patternRow);
+      }
+      patterns.add(pattern);
+    }
+
+    return patterns;
+  }
+
+  // Win game animation: rotating rays from center
+  static List createWinGameAnimationPatterns(Data myProvider) {
+    List<List> patterns = [];
+
+    int patternsCount = 20;
+    int sizeHorizontal = myProvider.sizeHorizontal;
+    int sizeVertical = myProvider.sizeVertical;
+
+    for (var patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
+      List<List> pattern = [];
+      for (var row = 0; row < sizeVertical; row++) {
+        List<bool> patternRow = [];
+        for (var col = 0; col < sizeHorizontal; col++) {
+          double angle = 2 * atan2((sizeVertical / 2) - col, (sizeHorizontal / 2) - row);
+          patternRow.add((angle + patternIndex / 3) % 2 < 1);
+        }
+        pattern.add(patternRow);
+      }
+      patterns.add(pattern);
+    }
+
+    return patterns;
+  }
+
+  // Default multi-purpose animation: sliding stripes, from top left to right bottom
+  static List createDefaultAnimationPatterns(Data myProvider) {
     List<List> patterns = [];
 
     int patternsCount = 16;
@@ -27,8 +117,23 @@ class BoardAnimate {
     return patterns;
   }
 
-  static void startAnimation(Data myProvider) {
-    List patterns = createPatterns(myProvider);
+  static void startAnimation(Data myProvider, String animationType) {
+    List patterns = [];
+
+    switch(animationType) {
+      case 'start':
+        patterns = createStartGameAnimationPatterns(myProvider);
+        break;
+      case 'win':
+        patterns = createWinGameAnimationPatterns(myProvider);
+        break;
+      case 'fail':
+        patterns = createExplosionAnimationPatterns(myProvider);
+        break;
+      default:
+        patterns = createDefaultAnimationPatterns(myProvider);
+    }
+
     int _patternIndex = patterns.length;
 
     myProvider.updateAnimationInProgress(true);
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
index 904838a..4e87a30 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';
 
 class GameUtils {
@@ -13,6 +14,7 @@ class GameUtils {
     myProvider.updateMinesCount(BoardUtils.getMinesCount(myProvider.sizeHorizontal, myProvider.sizeVertical, myProvider.level));
     myProvider.updateGameRunning(true);
     BoardUtils.createInitialEmptyBoard(myProvider);
+    BoardAnimate.startAnimation(myProvider, 'start');
   }
 
 }
-- 
GitLab