]> git.seodisparate.com - RockPaperScissorsDuel/commitdiff
Impl spectator view, refactorings/fixes
authorStephen Seo <seo.disparate@gmail.com>
Wed, 4 Jan 2023 04:55:25 +0000 (13:55 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Wed, 4 Jan 2023 04:55:25 +0000 (13:55 +0900)
src/constants.h
src/game.cc
src/game.h
src/helpers.cc
src/helpers.h
src/main.cc

index 5c0cc33655cd2c6d0826a939cd8007141751deb6..31f2869205ceb21068a716098bdc87cdd6315f30 100644 (file)
@@ -22,4 +22,6 @@ constexpr float SCORE_CHANGE_TIMER_MAX = 1.0F;
 
 constexpr float REQUEST_TIMER_MAX = 3.0F;
 
+constexpr int DEFAULT_STATUS_TEXT_SIZE = 30;
+
 #endif
index a4dc25fb883fa1be033ea253b02ba27103f60a49..8c0e775689a71f811a0e2672b4f089cdac7afe36 100644 (file)
 #include "helpers.h"
 
 Game::Game()
-    : spriteSheet(std::nullopt), status("Unknown status"), prevTime(0.0),
-      readyTimer(0.0F), resultsTimer(RESULTS_TIMER_MAX),
-      scoreChangeTimer(SCORE_CHANGE_TIMER_MAX), requestTimer(REQUEST_TIMER_MAX),
-      prevPos(0), cachedPos(0) {
+    : spriteSheet(std::nullopt), status("Unknown status"), readyTimer(0.0F),
+      resultsTimer(RESULTS_TIMER_MAX), scoreChangeTimer(SCORE_CHANGE_TIMER_MAX),
+      requestTimer(REQUEST_TIMER_MAX), prevPos(0), cachedPos(0),
+      statusSize(DEFAULT_STATUS_TEXT_SIZE) {
   spriteSheet = LoadTexture("resources/rockpaperscissorsSpriteSheet.png");
 
   picked[0] = 0;
@@ -86,12 +86,30 @@ void Game::update_state(const char *playerOne, const char *playerTwo,
 
   if (std::strcmp(currentPlayer, "undefined") == 0) {
     status = "Watching a Game...";
+    statusSize = Helpers::getFitableSize(
+        status.c_str(), DEFAULT_STATUS_TEXT_SIZE, GetScreenWidth());
     flags.set(2);
+    if (Helpers::isValidChoice(first_first) &&
+        Helpers::isValidChoice(first_second) &&
+        Helpers::isValidChoice(first_third)) {
+      picked[0] = first_first;
+      picked[1] = first_second;
+      picked[2] = first_third;
+    }
+    if (Helpers::isValidChoice(second_first) &&
+        Helpers::isValidChoice(second_second) &&
+        Helpers::isValidChoice(second_third)) {
+      opponentPicked[0] = second_first;
+      opponentPicked[1] = second_second;
+      opponentPicked[2] = second_third;
+    }
   } else if (std::strcmp(currentPlayer, playerOne) == 0) {
   } else if (std::strcmp(currentPlayer, playerTwo) == 0) {
   } else {
     // This should never happen.
     status = "unknown player";
+    statusSize = Helpers::getFitableSize(
+        status.c_str(), DEFAULT_STATUS_TEXT_SIZE, GetScreenWidth());
   }
 
   if (cachedPos != pos) {
@@ -105,22 +123,18 @@ void Game::do_update() {
   draw_impl();
 }
 
-void Game::update_impl() {
-  if (flags.test(2)) {
-    return;
-  }
-
-  float dt = 0.0F;
-  {
-    double timeNow = GetTime();
-    dt = timeNow - prevTime;
-    prevTime = timeNow;
-  }
+void Game::screen_size_changed() { flags.set(13); }
 
-  readyTimer -= dt;
-  if (readyTimer <= 0.0F) {
-    readyTimer = READY_TIMER_MAX;
-    flags.flip(1);
+void Game::update_impl() {
+  const float dt = GetFrameTime();
+
+  if (flags.test(13)) {
+    flags.reset(13);
+    statusSize =
+        !status.empty()
+            ? Helpers::getFitableSize(status.c_str(), DEFAULT_STATUS_TEXT_SIZE,
+                                      GetScreenWidth())
+            : DEFAULT_STATUS_TEXT_SIZE;
   }
 
   if (prevPos != cachedPos) {
@@ -131,6 +145,65 @@ void Game::update_impl() {
     }
   }
 
+  if (flags.test(2)) {
+    if (!flags.test(4) && Helpers::isValidChoice(picked[0]) &&
+        Helpers::isValidChoice(picked[1]) &&
+        Helpers::isValidChoice(picked[2]) &&
+        Helpers::isValidChoice(opponentPicked[0]) &&
+        Helpers::isValidChoice(opponentPicked[1]) &&
+        Helpers::isValidChoice(opponentPicked[2])) {
+      flags.set(4);
+      flags.set(5);
+      resultsTimer = RESULTS_TIMER_MAX;
+    } else if (flags.test(4)) {
+      resultsTimer -= dt;
+      if (resultsTimer <= 0.0F) {
+        resultsTimer = RESULTS_TIMER_MAX;
+        if (!flags.test(6)) {
+          flags.set(6);
+          flags.set(9);
+        } else if (!flags.test(7)) {
+          flags.set(7);
+          flags.set(9);
+        } else if (!flags.test(8)) {
+          flags.set(8);
+          flags.set(9);
+        } else {
+          flags.reset(4);
+          flags.reset(5);
+          flags.reset(6);
+          flags.reset(7);
+          flags.reset(8);
+          flags.reset(9);
+          flags.reset(10);
+          flags.reset(11);
+          picked[0] = '?';
+          picked[1] = '?';
+          picked[2] = '?';
+          opponentPicked[0] = '?';
+          opponentPicked[1] = '?';
+          opponentPicked[2] = '?';
+        }
+      }
+    }
+
+    if (IsMouseButtonPressed(0)) {
+      // TODO DEBUG
+      // if (GetTouchX() >= 0 && GetTouchX() <= 100 && GetTouchY() >= 0 &&
+      //    GetTouchY() <= 100) {
+      //  std::clog << "flags: " << flags.to_string().substr(32 - 14)
+      //            << std::endl;
+      //}
+    }
+    return;
+  }
+
+  readyTimer -= dt;
+  if (readyTimer <= 0.0F) {
+    readyTimer = READY_TIMER_MAX;
+    flags.flip(1);
+  }
+
   if (IsMouseButtonPressed(0) && !flags.test(0)) {
     int triple_single_width = GetScreenWidth() / 3.0F + 0.5F;
     if (triple_single_width > ICON_MAX_WIDTH) {
@@ -224,14 +297,21 @@ void Game::update_impl() {
     if (flags.test(0)) {
       if (flags.test(4)) {
         status.clear();
+        statusSize = DEFAULT_STATUS_TEXT_SIZE;
       } else {
         status = "Waiting...";
+        statusSize = Helpers::getFitableSize(
+            status.c_str(), DEFAULT_STATUS_TEXT_SIZE, GetScreenWidth());
       }
     } else {
       status = "Hit Ready!";
+      statusSize = Helpers::getFitableSize(
+          status.c_str(), DEFAULT_STATUS_TEXT_SIZE, GetScreenWidth());
     }
   } else {
     status = "Pick Moves!";
+    statusSize = Helpers::getFitableSize(
+        status.c_str(), DEFAULT_STATUS_TEXT_SIZE, GetScreenWidth());
   }
 
   if (flags.test(0) && flags.test(3) && flags.test(10) && flags.test(11)) {
@@ -324,7 +404,18 @@ void Game::draw_impl() {
     BeginDrawing();
     ClearBackground(BLACK);
     draw_score();
-    DrawText(status.c_str(), 0, 20, 30, RAYWHITE);
+    DrawText(status.c_str(), 0, 20, statusSize, RAYWHITE);
+
+    if (flags.test(4)) {
+      if (flags.test(5)) {
+        flags.reset(5);
+      }
+
+      float triple_single_width = GetScreenWidth() / 3.0F;
+      draw_reveal_choices(opponentPicked, triple_single_width);
+      draw_reveal_choices(picked, triple_single_width * 2.0F);
+    }
+
     EndDrawing();
     return;
   }
@@ -342,55 +433,7 @@ void Game::draw_impl() {
       draw_choice(0, picked[0], false, triple_single_width * 2.0F, WHITE);
       draw_choice(1, picked[1], false, triple_single_width * 2.0F, WHITE);
       draw_choice(2, picked[2], false, triple_single_width * 2.0F, WHITE);
-      float ratio = 1.0F - resultsTimer / RESULTS_TIMER_MAX;
-      char otherPicked =
-          Helpers::isValidChoice(opponentPicked[0]) ? opponentPicked[0] : '?';
-      if (!flags.test(6)) {
-        if (ratio < 1.0F) {
-          draw_choice(0, otherPicked, false, triple_single_width,
-                      {255, 255, 255, (unsigned char)(ratio * 255.0F)});
-          draw_qm(0, false, triple_single_width,
-                  {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)});
-        } else {
-          draw_choice(0, otherPicked, false, triple_single_width);
-        }
-      } else {
-        draw_choice(0, otherPicked, false, triple_single_width);
-      }
-
-      otherPicked =
-          Helpers::isValidChoice(opponentPicked[1]) ? opponentPicked[1] : '?';
-      if (!flags.test(7)) {
-        if (!flags.test(6)) {
-          draw_qm(1, false, triple_single_width, WHITE);
-        } else if (ratio < 1.0F) {
-          draw_choice(1, otherPicked, false, triple_single_width,
-                      {255, 255, 255, (unsigned char)(ratio * 255.0F)});
-          draw_qm(1, false, triple_single_width,
-                  {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)});
-        } else {
-          draw_choice(1, otherPicked, false, triple_single_width);
-        }
-      } else {
-        draw_choice(1, otherPicked, false, triple_single_width);
-      }
-
-      otherPicked =
-          Helpers::isValidChoice(opponentPicked[2]) ? opponentPicked[2] : '?';
-      if (!flags.test(8)) {
-        if (!flags.test(7)) {
-          draw_qm(2, false, triple_single_width, WHITE);
-        } else if (ratio < 1.0F) {
-          draw_choice(2, otherPicked, false, triple_single_width,
-                      {255, 255, 255, (unsigned char)(ratio * 255.0F)});
-          draw_qm(2, false, triple_single_width,
-                  {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)});
-        } else {
-          draw_choice(2, otherPicked, false, triple_single_width);
-        }
-      } else {
-        draw_choice(2, otherPicked, false, triple_single_width);
-      }
+      draw_reveal_choices(opponentPicked, triple_single_width);
     } else { // flags.test(0)
       unsigned char value = 0;
       if (flags.test(1)) {
@@ -451,7 +494,7 @@ void Game::draw_impl() {
     }
   }
   draw_score();
-  DrawText(status.c_str(), 0, 20, 20, RAYWHITE);
+  DrawText(status.c_str(), 0, 20, statusSize, RAYWHITE);
   EndDrawing();
 }
 
@@ -593,3 +636,52 @@ void Game::draw_score() const {
     DrawText(&buf[3], 0, 0, 20, WHITE);
   }
 }
+
+void Game::draw_reveal_choices(const char p[3], const float y) {
+  float ratio = 1.0F - resultsTimer / RESULTS_TIMER_MAX;
+  char otherPicked = Helpers::isValidChoice(p[0]) ? p[0] : '?';
+  if (!flags.test(6)) {
+    if (ratio < 1.0F) {
+      draw_choice(0, otherPicked, false, y,
+                  {255, 255, 255, (unsigned char)(ratio * 255.0F)});
+      draw_qm(0, false, y,
+              {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)});
+    } else {
+      draw_choice(0, otherPicked, false, y);
+    }
+  } else {
+    draw_choice(0, otherPicked, false, y);
+  }
+
+  otherPicked = Helpers::isValidChoice(p[1]) ? p[1] : '?';
+  if (!flags.test(7)) {
+    if (!flags.test(6)) {
+      draw_qm(1, false, y, WHITE);
+    } else if (ratio < 1.0F) {
+      draw_choice(1, otherPicked, false, y,
+                  {255, 255, 255, (unsigned char)(ratio * 255.0F)});
+      draw_qm(1, false, y,
+              {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)});
+    } else {
+      draw_choice(1, otherPicked, false, y);
+    }
+  } else {
+    draw_choice(1, otherPicked, false, y);
+  }
+
+  otherPicked = Helpers::isValidChoice(p[2]) ? p[2] : '?';
+  if (!flags.test(8)) {
+    if (!flags.test(7)) {
+      draw_qm(2, false, y, WHITE);
+    } else if (ratio < 1.0F) {
+      draw_choice(2, otherPicked, false, y,
+                  {255, 255, 255, (unsigned char)(ratio * 255.0F)});
+      draw_qm(2, false, y,
+              {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)});
+    } else {
+      draw_choice(2, otherPicked, false, y);
+    }
+  } else {
+    draw_choice(2, otherPicked, false, y);
+  }
+}
index 4c4999753663aa1ddfff53b01c97fcf578c65c37..f95fa41269ed444da15dfc7837c6194c31cc18f0 100644 (file)
@@ -21,6 +21,8 @@ public:
 
   void do_update();
 
+  void screen_size_changed();
+
 private:
   void update_impl();
   void draw_impl();
@@ -38,12 +40,12 @@ private:
   bool is_opponent_choices_set() const;
 
   void draw_score() const;
+  void draw_reveal_choices(const char p[3], const float y);
 
   std::optional<Texture2D> spriteSheet;
   std::string playerOne;
   std::string playerTwo;
   std::string status;
-  double prevTime;
   /*
    * 0 - ready flag (ready to submit moves)
    * 1 - readyTimer fade to gray (fade to black otherwise)
@@ -58,6 +60,7 @@ private:
    * 10 - first ready
    * 11 - second ready
    * 12 - ready state dirty
+   * 13 - screen size changed
    */
   std::bitset<32> flags;
   float readyTimer;
@@ -66,6 +69,7 @@ private:
   float requestTimer;
   int prevPos;
   int cachedPos;
+  int statusSize;
   char picked[3];
   char opponentPicked[3];
   bool isPlayerOne;
index d8c277e974d2bec98e5d05a9a10ac9871d3658be..0d9a9ded5ed7404ae5bbc2006412147ed469558b 100644 (file)
@@ -1,5 +1,21 @@
 #include "helpers.h"
 
+// third party includes
+#include <raylib.h>
+
 bool Helpers::isValidChoice(char choice) {
   return choice == 'r' || choice == 'p' || choice == 's';
 }
+
+int Helpers::getFitableSize(const char *text, const int default_size,
+                            const int width) {
+  int size = default_size;
+  while (MeasureText(text, size) > width) {
+    --size;
+    if (size <= 8) {
+      break;
+    }
+  }
+
+  return size;
+}
index 9dcc0ce4834c18318dd6021dcd0ee0ec81086261..a98027e487714e53d157b42fc53e5fc883565234 100644 (file)
@@ -4,7 +4,9 @@
 namespace Helpers {
 
 extern bool isValidChoice(char choice);
+extern int getFitableSize(const char *text, const int default_size,
+                          const int width);
 
-}
+} // namespace Helpers
 
 #endif
index f0ecff5e8d604c1fb4549c563cd43ef7e287f7d4..eddd6f6677173815dfa0970b2e2b1d6baa201f77 100644 (file)
@@ -39,6 +39,7 @@ EM_BOOL resize_event_callback(int event_type, const EmscriptenUiEvent *event,
                               void *ud) {
   if (event_type == EMSCRIPTEN_EVENT_RESIZE) {
     SetWindowSize(call_js_get_canvas_width(), call_js_get_canvas_height());
+    ((Game *)ud)->screen_size_changed();
   }
   return false;
 }
@@ -61,7 +62,7 @@ int main() {
 
   SetWindowSize(call_js_get_canvas_width(), call_js_get_canvas_height());
 
-  emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, false,
+  emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, &game, false,
                                  resize_event_callback);
 
   emscripten_set_main_loop_arg(game_update, &game, 0, 1);