Simon游戏:showMoves未执行完时game.playerTurn提前置为true的问题
showMoves Player Turn Timing It sounds like your issue is that game.playerTurn is getting set to true immediately when showMoves runs, instead of waiting until all the light flashes are complete. Let's break down how to fix this.
The Root Problem
Your current code is probably setting game.playerTurn = true in the synchronous part of showMoves (outside the timer logic). Since timers like setInterval or setTimeout run asynchronously, that line executes right away—before any of the light flashes even start.
The Solution: Only Unlock Player Turn After All Flashes Finish
We need to delay setting game.playerTurn = true until the entire sequence of light flashes has completed. Here's a reliable way to implement this:
Example Implementation
// Lock player input before starting the sequence game.playerTurn = false; function showMoves() { let currentMoveIndex = 0; const moveSequence = game.moves; // Your array of colors to flash const flashDelay = 800; // Total time per flash (on + off) // Recursive function to handle each flash in sequence function flashNext() { // Exit condition: all moves have been flashed if (currentMoveIndex >= moveSequence.length) { // Now unlock player input game.playerTurn = true; return; } // Get the current color and trigger its flash const color = moveSequence[currentMoveIndex]; triggerFlash(color); // Move to the next move and schedule the next flash currentMoveIndex++; setTimeout(flashNext, flashDelay); } // Start the flash sequence flashNext(); } // Helper function to handle the light on/off logic function triggerFlash(colorId) { const light = document.getElementById(colorId); // Turn the light on light.classList.add('active'); // Turn it off after half the total delay setTimeout(() => { light.classList.remove('active'); }, flashDelay / 2); }
Key Details to Note:
- We use recursive
setTimeoutinstead ofsetIntervalhere—it's more reliable for sequential actions, as it ensures each flash finishes before the next starts. game.playerTurn = trueis only called inside the exit condition offlashNext, which runs after the last flash has been scheduled and completed.- Make sure you don't have any
game.playerTurn = truelines in the top-level ofshowMoves—those would run immediately and break the timing.
Quick Check for Existing Code
If you were using setInterval before, adjust it to clear the interval and set playerTurn only when the sequence ends:
function showMoves() { let i = 0; const interval = setInterval(() => { // Your flash logic here for game.moves[i] i++; if (i >= game.moves.length) { clearInterval(interval); // THIS IS WHERE YOU SET playerTurn TO TRUE game.playerTurn = true; } }, 800); // Remove any game.playerTurn = true from this area! }
This way, the player can only interact with the game once the full sequence of flashes has finished playing.
内容的提问来源于stack exchange,提问作者icewizard

