Show garbage received on player elimination

- Add garbageReceived array to player objects
- Track garbage in addGarbageToPlayer() with sender name
- Include garbageReceived in getStates() output
- Update endGame() to pass garbage stats to UI
- Update showGameOver() to display garbage count per player
- Add CSS styling for eliminated players and garbage column
- Bump CSS version for cache refresh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 02:44:39 +00:00
parent a1cbd27a71
commit e3f594e44e
5 changed files with 29 additions and 7 deletions
+10
View File
@@ -397,6 +397,16 @@ button:active {
color: #0f0; color: #0f0;
} }
#final-scores .score-item.eliminated {
border-color: #f00;
opacity: 0.7;
}
#final-scores .score-item span:last-child {
color: #888;
font-size: 0.7rem;
}
/* Game Over Overlay */ /* Game Over Overlay */
#gameover-screen { #gameover-screen {
position: fixed; position: fixed;
+1 -1
View File
@@ -7,7 +7,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/style.css?v=10"> <link rel="stylesheet" href="css/style.css?v=11">
</head> </head>
<body> <body>
<div id="app"> <div id="app">
+6 -2
View File
@@ -214,11 +214,15 @@ function endGame(states) {
winner = winnerPlayer.name; winner = winnerPlayer.name;
} }
// Build scores list // Build scores list with garbage info
Object.values(states).forEach(state => { Object.values(states).forEach(state => {
const player = network.getPlayer(state.playerId); const player = network.getPlayer(state.playerId);
if (player) { if (player) {
scores[player.name] = state.score; scores[player.name] = {
score: state.score,
garbageReceived: (state.garbageReceived || []).length,
eliminated: state.eliminated
};
} }
}); });
+4 -2
View File
@@ -140,12 +140,14 @@ class UIManager {
this.displays.winnerDisplay.style.color = winner ? '#0f0' : '#fff'; this.displays.winnerDisplay.style.color = winner ? '#0f0' : '#fff';
this.displays.finalScores.innerHTML = ''; this.displays.finalScores.innerHTML = '';
Object.entries(scores).forEach(([name, score], index) => { Object.entries(scores).forEach(([name, data], index) => {
const item = document.createElement('div'); const item = document.createElement('div');
item.className = 'score-item' + (index === 0 ? ' winner' : ''); item.className = 'score-item' + (index === 0 ? ' winner' : '');
if (data.eliminated) item.classList.add('eliminated');
item.innerHTML = ` item.innerHTML = `
<span>${this.escapeHtml(name)}</span> <span>${this.escapeHtml(name)}</span>
<span>${score}</span> <span>Score: ${data.score}</span>
<span class="garbage">Garbage: ${data.garbageReceived}</span>
`; `;
this.displays.finalScores.appendChild(item); this.displays.finalScores.appendChild(item);
}); });
+8 -2
View File
@@ -115,7 +115,8 @@ io.on('connection', (socket) => {
eliminated: false, eliminated: false,
ready: false, ready: false,
dropCounter: 0, dropCounter: 0,
dropInterval: 1000 dropInterval: 1000,
garbageReceived: []
}; };
lobby.players.set(socket.id, player); lobby.players.set(socket.id, player);
@@ -479,6 +480,9 @@ function addGarbageToPlayer(player, senderName) {
garbageRow[gap] = 0; garbageRow[gap] = 0;
player.board.push(garbageRow); player.board.push(garbageRow);
// Track garbage received
player.garbageReceived.push({ rows: 1, sender: senderName });
// Push current piece up by 1 row if it exists (y decreases when moving up) // Push current piece up by 1 row if it exists (y decreases when moving up)
if (player.currentPiece) { if (player.currentPiece) {
const oldY = player.currentPiece.y; const oldY = player.currentPiece.y;
@@ -519,6 +523,7 @@ function startGame() {
player.dropInterval = 1000; player.dropInterval = 1000;
player.holdPiece = null; player.holdPiece = null;
player.canHold = true; player.canHold = true;
player.garbageReceived = [];
lobby.playerSequenceIndex.set(player.id, 0); lobby.playerSequenceIndex.set(player.id, 0);
} }
@@ -578,7 +583,8 @@ function getStates() {
lines: p.lines, lines: p.lines,
level: p.level, level: p.level,
eliminated: p.eliminated, eliminated: p.eliminated,
sequenceIndex: lobby.playerSequenceIndex.get(p.id) || 0 sequenceIndex: lobby.playerSequenceIndex.get(p.id) || 0,
garbageReceived: p.garbageReceived ? JSON.parse(JSON.stringify(p.garbageReceived)) : []
})); }));
} }