Add hold piece feature
- Added holdPiece and canHold state to TetrisGame class - Implemented hold() method to swap current piece with held piece - Added player-hold socket event on server - Added HOLD preview canvas showing held piece (grayed when unavailable) - Added C key keyboard shortcut and touch button for hold - Fixed canHold reset on piece spawn for proper swap functionality Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -159,6 +159,42 @@ io.on('connection', (socket) => {
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('player-hold', ({ playerId }) => {
|
||||
if (!lobby.gameStarted) return;
|
||||
|
||||
const player = lobby.players.get(playerId);
|
||||
if (!player || player.eliminated) return;
|
||||
if (!player.canHold) return;
|
||||
|
||||
if (player.holdPiece === null) {
|
||||
// First hold - store current piece and spawn next
|
||||
player.holdPiece = {
|
||||
type: player.currentPiece.type,
|
||||
shape: JSON.parse(JSON.stringify(player.currentPiece.shape)),
|
||||
color: player.currentPiece.color
|
||||
};
|
||||
player.currentPiece = player.nextPiece;
|
||||
player.nextPiece = getRandomPiece();
|
||||
} else {
|
||||
// Swap with held piece
|
||||
const temp = {
|
||||
type: player.currentPiece.type,
|
||||
shape: JSON.parse(JSON.stringify(player.currentPiece.shape)),
|
||||
color: player.currentPiece.color
|
||||
};
|
||||
player.currentPiece = {
|
||||
...player.holdPiece,
|
||||
shape: JSON.parse(JSON.stringify(player.holdPiece.shape)),
|
||||
x: Math.floor(BOARD_WIDTH / 2) - Math.floor(player.holdPiece.shape[0].length / 2),
|
||||
y: 0
|
||||
};
|
||||
player.holdPiece = temp;
|
||||
}
|
||||
|
||||
player.canHold = false;
|
||||
broadcastState();
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
const player = lobby.players.get(socket.id);
|
||||
if (player) {
|
||||
@@ -254,6 +290,9 @@ function lockPiece(player) {
|
||||
|
||||
if (!spawnPiece(player)) player.eliminated = true;
|
||||
|
||||
// Reset canHold for the new piece
|
||||
player.canHold = true;
|
||||
|
||||
if (rowsCleared > 0) sendGarbage(player, rowsCleared);
|
||||
|
||||
broadcastState();
|
||||
@@ -309,6 +348,8 @@ function startGame() {
|
||||
player.level = 1;
|
||||
player.eliminated = false;
|
||||
player.dropInterval = 1000;
|
||||
player.holdPiece = null;
|
||||
player.canHold = true;
|
||||
player.currentPiece = getRandomPiece();
|
||||
player.nextPiece = getRandomPiece();
|
||||
}
|
||||
@@ -351,6 +392,8 @@ function getStates() {
|
||||
board: JSON.parse(JSON.stringify(p.board)),
|
||||
currentPiece: p.currentPiece ? JSON.parse(JSON.stringify(p.currentPiece)) : null,
|
||||
nextPiece: p.nextPiece ? JSON.parse(JSON.stringify(p.nextPiece)) : null,
|
||||
holdPiece: p.holdPiece ? JSON.parse(JSON.stringify(p.holdPiece)) : null,
|
||||
canHold: p.canHold,
|
||||
score: p.score,
|
||||
lines: p.lines,
|
||||
level: p.level,
|
||||
|
||||
Reference in New Issue
Block a user