暂停函数在JavaScript中导致问题



我想在暂停后恢复游戏,但它冻结了游戏,但在恢复后,游戏只给你一个键,分数在0和你实际拥有的分数之间出现故障。

我尝试使用clearTimeout()函数来停止函数,存储计时器,生命,分数和当前键,但它似乎卡住了我给它的一个键。

这是暂停函数:

function pause() {
window.addEventListener("keydown", (event) => {
if (event.key == 'Tab') {
if (!isPaused) {
isPaused = true;
gameIsPlaying = false;
window.currentKey = item
window.currentScore = score
window.currentTime = seconds
window.currentLives = lives
console.log(currentKey, currentScore, currentTime)
clearTimeout(timerId);
clearTimeout(updateLives);
clearTimeout(ScoreUpdate);
bars.forEach((bar) => {
bar.style.animationPlayState = 'paused';
})
AudioElement.pause();
} else {
isPaused = false;
item = currentKey
score = currentScore
seconds = currentTime
lives = currentLives
game(item, seconds, lives, score);
bars.forEach((bar) => {
bar.style.animationPlayState = 'running';
})
AudioElement.play();
}
}
})
}

JSFiddle: https://jsfiddle.net/b30osaLp/(Tab键暂停游戏)

编辑:我尝试了@code在评论中的解决方案。

window.addEventListener("keydown", (event) => {
if (event.key == 'Tab') {
pause();
}
})
function pause() {
if (!isPaused) {
isPaused = true;
gameIsPlaying = false;
clearTimeout(timerId);
clearTimeout(updateLives);
clearTimeout(ScoreUpdate);
bars.forEach((bar) => {
bar.style.animationPlayState = 'paused';
})
AudioElement.pause();
} else {
isPaused = false;
game();
bars.forEach((bar) => {
bar.style.animationPlayState = 'running';
})
AudioElement.play();
}
}

但它仍然产生同样的问题。

我已经设法让你的代码工作,虽然我已经重写了大部分。

我删除了所有无关的功能,如AudioElement和动画计时器。我简化了你的HTML和CSS。

您有3个setIntervals,我已经删除了ScoreLives间隔,并在需要时更新相关信息来替换它们。

我已将所有事件处理程序整理为每个事件类型。

并使用bindElementstyleElement函数来整理代码。

所以现在你可以暂停和重新开始游戏!(使用Q-TAB有其他用途,会干扰页面上的其他代码)

window.focus();
var paused, timerId;
var item, pickTime;
var seconds, lives, score;
const keys = ["W", "A", "S", "D", "Q", "ENTER"];
function bindElement(ref) {
return document.getElementById(ref);
}
function styleElement(ref, clr, txt) {
ref.style.backgroundColor = clr;
ref.innerHTML = txt;
}
const LetterGUI = bindElement("Letter");
const TimerGUI = bindElement("Timer");
const LivesGUI = bindElement("Lives");
const ScoreGUI = bindElement("Score");
const W = bindElement("W");
const A = bindElement("A");
const S = bindElement("S");
const D = bindElement("D");
const PA = bindElement("playAgain");
document.onkeydown = function(e) {
var key = e.key.toUpperCase();
if (!keys.includes(key)) return;
if (key == 'Q') {
if (!paused) {
paused = true;
clearTimeout(timerId);
} else {
paused = false;
timerId = setTimeout(countdown, 0);
}
return;
}
if (key == "ENTER" && PA.style.visibility == "visible") {
game();
return;
}
if (key != item) {
lives--;
score -= 50;
if (lives < 1) {
gameOver();
return;
}
} else {
var elapsed = Math.floor(Date.now() / 1000) - pickTime;
if (elapsed < 1.5) score += 500;
else if (elapsed < 3) score += 350;
else if (elapsed < 5) score += 150;
}
ScoreGUI.innerHTML = "Score: " + score;
LivesGUI.innerHTML = "Lives: " + lives;
if (key == "W")
if (key == item) styleElement(W, 'lime', '');
else styleElement(W, 'red', '');
if (key == "A")
if (key == item) styleElement(A, 'lime', '');
else styleElement(A, 'red', '');
if (key == "S")
if (key == item) styleElement(S, 'lime', '');
else styleElement(S, 'red', '');
if (key == "D")
if (key == item) styleElement(D, 'lime', '');
else styleElement(D, 'red', '');
letter();
}
document.onkeyup = function(e) {
var key = e.key.toUpperCase();
if (key == "W") styleElement(W, 'white', 'W');
if (key == "A") styleElement(A, 'white', 'A');
if (key == "S") styleElement(S, 'white', 'S');
if (key == "D") styleElement(D, 'white', 'D');
}
function letter() {
item = keys[Math.floor(Math.random() * 4)];
LetterGUI.innerHTML = "Letter: " + item;
pickTime = Math.floor(Date.now() / 1000);
}
game();
function game() {
paused = false;
styleElement(W, 'white', 'W');
styleElement(A, 'white', 'A');
styleElement(S, 'white', 'S');
styleElement(D, 'white', 'D')
TimerGUI.style.color = "white";
PA.style.visibility = "hidden";
seconds = 20;
lives = 3;
score = 0;
letter();
ScoreGUI.innerHTML = "Score: " + score;
LivesGUI.innerHTML = "Lives: " + lives;
timerId = setTimeout(countdown, 0);
}
function countdown() {
seconds--;
if (seconds < 0) {
gameOver();
return;
}
if (seconds <= 5) TimerGUI.style.color = "red";
if (seconds > 9) TimerGUI.innerHTML = "Time: " + seconds;
else TimerGUI.innerHTML = "Time: 0" + seconds;
timerId = setTimeout(countdown, 1000);
}
function gameOver() {
clearTimeout(timerId);
styleElement(W, 'red', '');
styleElement(A, 'red', '');
styleElement(S, 'red', '');
styleElement(D, 'red', '')
LetterGUI.innerHTML = "";
TimerGUI.innerHTML = "";
ScoreGUI.innerHTML = "Score: " + score;
LivesGUI.innerHTML = "Lives: " + lives;
PA.style.visibility = "visible";
}
body {
background-color: #abcdef
}
.info {
color: white;
font-size: 18px
}
.letter {
height: 50px;
width: 50px;
text-align: center
}
.center {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
bottom: 100px;
left: 0;
right: 0
}
.footer {
position: fixed;
text-align: center;
bottom: 0px;
width: 100%;
font-size: 22px;
color: green;
font-family: "Courier New"
}
<div id="Letter" class="info"></div>
<div id="Lives" class="info"></div>
<div id="Score" class="info"></div>
<div id="Timer" class="info"></div>
<table class="center">
<tr>
<td></td>
<td id="W" class="letter"></td>
<td></td>
</tr>
<tr>
<td id="A" class="letter"></td>
<td id="S" class="letter"></td>
<td id="D" class="letter"></td>
</tr>
</table>
<span id="playAgain" class="footer">Press [Enter] to restart</span>

你确定要从setInterval(resetGame, 0)开始游戏吗?

这将重复重置游戏,每0毫秒

也许你打算在0毫秒超时后启动它,即一旦解释器下一次空闲:

setTimeout(resetGame, 0);

当我在你的小提琴上改变它时,它似乎像预期的那样工作。

最新更新