Add spectator mode for late-joining players
- Server: Late joiners are added as spectators instead of players - Server: Send forced-spectator event only to joining spectator (not broadcast) - Server: Track spectators separately and move them to players after game ends - Client: Handle forced-spectator event to show all player boards - Client: Spectators see all boards equally without main/spectator highlighting - Client: Mobile view shows scrollable vertical list of all boards for spectators - Fix: All cleared lines are sent as garbage to each opponent (not randomized) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+63
-1
@@ -151,6 +151,44 @@ button:active {
|
||||
color: #0f0;
|
||||
}
|
||||
|
||||
.player-item .status.spectator-status {
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Spectator list in lobby */
|
||||
#spectator-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin: 20px 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
#spectator-list:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#spectator-list .player-item {
|
||||
background: #0a0a1a;
|
||||
border: 2px solid #555;
|
||||
}
|
||||
|
||||
#spectator-list .player-item .status {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
/* Spectator mode header */
|
||||
#game-room-name.spectator-mode {
|
||||
color: #ff8800;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.7; }
|
||||
}
|
||||
|
||||
/* Battle Grid - Focused Layout */
|
||||
#battle-grid {
|
||||
position: relative;
|
||||
@@ -538,7 +576,31 @@ button:active {
|
||||
height: 50px !important;
|
||||
}
|
||||
|
||||
.player-board.spectator {
|
||||
/* Hide spectator boards on mobile when playing (has main board) */
|
||||
#battle-grid:has(.main) .player-board.spectator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* In spectator mode (no main board), show all boards in a scrollable container */
|
||||
#battle-grid:not(:has(.main)) {
|
||||
transform: none;
|
||||
height: auto;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
#battle-grid:not(:has(.main)) .player-board {
|
||||
position: relative;
|
||||
transform: none;
|
||||
opacity: 1;
|
||||
margin: 10px 0;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
#battle-grid:not(:has(.main)) .player-board canvas {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user