Display (grayed out) inactive players with non-zero scores
authorCarl Worth <cworth@cworth.org>
Tue, 30 Jun 2020 00:09:31 +0000 (17:09 -0700)
committerCarl Worth <cworth@cworth.org>
Tue, 30 Jun 2020 00:09:31 +0000 (17:09 -0700)
This issue came up with playtesting last night: We had a player who
finished in the top three overall, but dropped out for the last couple
of rounds. But we still wanted to see their score in the final
results. So, here we keep track of active and inactive players and
display the inactive ones (if they have non-zero score) with 50%
opacity.

empathy/empathy.css
empathy/empathy.jsx

index adc8f6aa7f213616f91afcee984d7288e8bcfe5f..a32f2de96fa2f2843eeb3b4e602d6c43bb03542a 100644 (file)
     color: var(--accent-color-bright);
     opacity: 1.0;
 }
+
+.player-idle {
+    opacity: 0.5;
+}
index 7ac92e01e4532eb35bd73fd2c878afca01fcc597..b58f9359ff5bdc7bed3bef174cc6119ee7cee0b7 100644 (file)
@@ -48,7 +48,7 @@ events.addEventListener("player-enter", event => {
 events.addEventListener("player-exit", event => {
   const info = JSON.parse(event.data);
 
-  window.game.remove_player(info);
+  window.game.disable_player(info);
 });
 
 events.addEventListener("player-update", event => {
@@ -227,23 +227,43 @@ const PlayerInfo = React.memo(props => {
   if (! props.player.id)
     return null;
 
-  const all_players = [props.player, ...props.other_players];
+  const all_players = [{...props.player, active:true}, ...props.other_players];
 
   const sorted_players = all_players.sort((a,b) => {
     return b.score - a.score;
   });
 
-  const names_and_scores = sorted_players.map(player => {
-    if (player.score)
-      return `${player.name} (${player.score})`;
-    else
-      return player.name;
-  }).join(', ');
+  /* Return a new array with the separator interspersed between
+   * each element of the array passed in as the argument.
+   */
+  function intersperse(arr, sep) {
+    return arr.reduce((acc, val) => [...acc, sep, val], []).slice(1);
+  }
+
+  let names_and_scores = sorted_players.map(player => {
+    if (player.score) {
+      return (
+        <span
+          key={player.name}
+          className={player.active ? "player-active" : "player-idle"}
+        >
+        {player.name} ({player.score})
+        </span>
+      );
+    } else {
+      if (player.active)
+        return player.name;
+      else
+        return null;
+    }
+  }).filter(component => component != null);
+
+  names_and_scores = intersperse(names_and_scores, ", ");
 
   return (
     <div className="player-info">
       <span className="players-header">Players: </span>
-      <span>{names_and_scores}</span>
+      {names_and_scores}
     </div>
   );
 });
@@ -976,21 +996,29 @@ class Game extends React.PureComponent {
   }
 
   set_other_player_info(info) {
+    const player_object = {...info, active: true};
     const other_players_copy = [...this.state.other_players];
     const idx = other_players_copy.findIndex(o => o.id === info.id);
     if (idx >= 0) {
-      other_players_copy[idx] = info;
+      other_players_copy[idx] = player_object;
     } else {
-      other_players_copy.push(info);
+      other_players_copy.push(player_object);
     }
     this.setState({
       other_players: other_players_copy
     });
   }
 
-  remove_player(info) {
+  disable_player(info) {
+    const idx = this.state.other_players.findIndex(o => o.id === info.id);
+    if (idx < 0)
+      return;
+
+    const other_players_copy = [...this.state.other_players];
+    other_players_copy[idx].active = false;
+
     this.setState({
-      other_players: this.state.other_players.filter(o => o.id !== info.id)
+      other_players: other_players_copy
     });
   }