From d550b880dd36e23491e9cf9d182b39920d7c113c Mon Sep 17 00:00:00 2001
From: Jan Grewe <jan@faked.org>
Date: Thu, 1 Jun 2023 00:20:36 +0200
Subject: [PATCH] smoother game reset WIP: fade game out

---
 src/display.cpp    | 36 ++++++++++++++++++-------------
 src/display.h      |  4 +++-
 src/gameoflife.cpp | 54 +++++++++++++++++++++++++++++++++-------------
 src/main.cpp       |  4 ++--
 4 files changed, 65 insertions(+), 33 deletions(-)

diff --git a/src/display.cpp b/src/display.cpp
index 54efa26..66b6da2 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -27,6 +27,7 @@ void setupDisplay()
   matrix.addLayer(&indexedLayer);
   matrix.begin();
   matrix.setBrightness(defaultBrightness);
+  backgroundLayer.setBrightness(255);
   backgroundLayer.enableColorCorrection(true);
 }
 
@@ -45,27 +46,32 @@ void displayLoop()
   }
 }
 
-void fadeOut(int ticks)
-{
-  const uint transitionTime = 5000;
-  unsigned long currentMillis = millis();
+void showEndScreen(int ticks) {
+  showEvolutions(ticks);
+}
 
-  while (millis() - currentMillis < transitionTime)
-  {
-    char evolutions[16];
-    sprintf(evolutions, "Evolutions: %d", ticks);
-    char msg[] = "Life has ended";
-    indexedLayer.setFont(font3x5);
-    indexedLayer.drawString((matrix.getScreenWidth() / 2) - (strlen(msg) * 4) / 2, (matrix.getScreenHeight() / 2) - 2 - 5 , 1, msg);
-    indexedLayer.drawString((matrix.getScreenWidth() / 2) - (strlen(evolutions) * 4) / 2, (matrix.getScreenHeight() / 2) + 2, 1, evolutions);
-    indexedLayer.swapBuffers();
-    indexedLayer.fillScreen(0);
-  }
+void fadeOutGame(int brightness) {
+  brightness = lightPowerMap8bit[brightness];
+  backgroundLayer.setBrightness(brightness);
+  backgroundLayer.swapBuffers();
+}
+
+void showEvolutions(int ticks)
+{
+  char msg[15] = "Life has ended";
+  char evolutions[17];
+  sprintf(evolutions, "Evolutions: %d", ticks);
+  indexedLayer.setFont(font3x5);
+  indexedLayer.drawString((matrix.getScreenWidth() / 2) - (strlen(msg) * 4) / 2, (matrix.getScreenHeight() / 2) - 2 - 5 , 1, msg);
+  indexedLayer.drawString((matrix.getScreenWidth() / 2) - (strlen(evolutions) * 4) / 2, (matrix.getScreenHeight() / 2) + 2, 1, evolutions);
   indexedLayer.swapBuffers();
+  indexedLayer.fillScreen(0);
 }
 
 void clearDisplay()
 {
+  indexedLayer.swapBuffers();
   backgroundLayer.fillScreen({0, 0, 0});
+  backgroundLayer.setBrightness(255);
   backgroundLayer.swapBuffers();
 }
diff --git a/src/display.h b/src/display.h
index ffb9579..fa92192 100644
--- a/src/display.h
+++ b/src/display.h
@@ -10,7 +10,9 @@ extern int brightnessPercent;
 
 void setupDisplay();
 void displayLoop();
-void fadeOut(int ticks);
+void showEndScreen(int ticks);
+void fadeOutGame(int brightness);
+void showEvolutions(int ticks);
 void clearDisplay();
 
 #endif
diff --git a/src/gameoflife.cpp b/src/gameoflife.cpp
index a9c7554..c508f3d 100644
--- a/src/gameoflife.cpp
+++ b/src/gameoflife.cpp
@@ -8,19 +8,27 @@ int g[SCREEN_HEIGHT][SCREEN_WIDTH];
 int arrayCopy[SCREEN_HEIGHT][SCREEN_WIDTH];
 
 bool runGame = true;
+bool gameOver = false;
 
 int currentTick;
+int finalTicks;
 int cellsAliveBefore;
 int noEvolutionTicks;
 
+const uint scoreScreenTimeout = 5000;
+unsigned long currentMillis;
+
 void setupGameOfLife()
 {
+  gameOver = false;
   currentTick = 0;
+  finalTicks = 0;
   cellsAliveBefore = 0;
   noEvolutionTicks = 0;
   randomSeed(analogRead(34));
   createRandomMatrix(g);
-  for (int i = 0; i < 10; i++) {
+  for (int i = 0; i < 10; i++)
+  {
     addGlider(random(SCREEN_HEIGHT), random(SCREEN_WIDTH), g);
   }
 }
@@ -40,7 +48,7 @@ void gameOfLife(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH])
 {
   currentTick++;
   int cellsAliveNow = 0;
- 
+
   for (int i = 0; i < SCREEN_HEIGHT; i++)
   {
     for (int j = 0; j < SCREEN_WIDTH; j++)
@@ -64,6 +72,7 @@ void gameOfLife(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH])
         if (total < 2 || total > 3)
         {
           arrayCopy[i][j] = 0;
+          cellsAliveNow--;
         }
       }
       else if (total == 3)
@@ -81,12 +90,14 @@ void gameOfLife(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH])
       a[i][j] = arrayCopy[i][j];
     }
   }
-  
-  if (currentTick % 2) {
+
+  if (currentTick % 2)
+  {
     cellsAliveBefore = cellsAliveNow;
   }
-  
-  if (cellsAliveNow == cellsAliveBefore)
+
+  if (cellsAliveNow >= cellsAliveBefore - 3 &&
+      cellsAliveNow <= cellsAliveBefore + 3)
   {
     noEvolutionTicks++;
   }
@@ -97,7 +108,16 @@ void gameOfLife(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH])
 
   if (noEvolutionTicks > noEvolutionTicksLimit)
   {
-    endGame();
+    if (!gameOver)
+    {
+      finalTicks = currentTick - noEvolutionTicksLimit;
+      currentMillis = millis();
+      showEndScreen(finalTicks);
+      gameOver = true;
+    } else {
+      int brightness = 255 * (1 - ((millis() - currentMillis) / scoreScreenTimeout));
+      fadeOutGame(brightness);
+    }
   }
 }
 
@@ -118,17 +138,21 @@ void addGlider(int i1, int j1, int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH])
 
 void gameLoop()
 {
-  if (runGame) {
+  if (runGame)
+  {
     gameOfLife(g);
+    if (gameOver)
+    {
+      if (millis() - currentMillis > scoreScreenTimeout)
+      {
+        resetGame();
+      }
+    }
   }
 }
 
-void endGame() {
-  fadeOut(currentTick - noEvolutionTicksLimit);
-  resetGame();
-}
-
-void resetGame() {
-  clearDisplay();
+void resetGame()
+{
   setupGameOfLife();
+  clearDisplay();
 }
diff --git a/src/main.cpp b/src/main.cpp
index 02936ab..7c915f0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5,14 +5,14 @@
 #include "gameoflife.h"
 
 int noEvolutionTicksLimit = 100;
-int brightnessPercent = 20;
+int brightnessPercent = 100;
 
 void setup()
 {
   Serial.begin(115200);
   logLine("", true);
-  setupNetwork();
   setupDisplay();
+  setupNetwork();
   setupGameOfLife();
 }
 
-- 
GitLab