我使用javascript画布制作了经典的Snake街机游戏,并且我尝试构建内置功能以减小游戏动画的运行间隔。如果您不熟悉Snake,则蛇会在屏幕上四处移动,并尝试吃掉随机出现的苹果,同时尽量不碰到自己或墙壁。蛇每次吃一个苹果,它的大小就会变长,游戏也会变得更加困难。我试图通过每次蛇吃一个苹果时加快游戏速度来增加游戏难度。我已经在下面的代码片段中实现了这一点:
//Animate the game
function gameLoop() {
ctx.clearRect(0, 0, width, height);
drawScore();
snake.move();
snake.draw();
apple.draw();
drawBorder();
var timeoutID = setTimeout(function() {
gameLoop();
}, interval);
};
gameLoop(); //call the game loop
问题是我有一个
gameOver()
函数可以访问运行游戏的timeoutId
函数的setTimeout
,但是timeoutId
变量未在gameOver()
函数中定义。为了使事情更加混乱,gameOver
函数在预期的时候仍然可以工作,但是会在控制台中产生一个错误,提示:Uncaught ReferenceError: timeoutID is not defined
at gameOver (snake.html:68)
at Snake.move (snake.html:157)
at gameLoop (snake.html:253)
at snake.html:258
并且
gameOver()
函数未按预期运行。它应该显示“游戏结束”并显示玩家的最后得分,并简单地显示未做出的蛇。相反,当调用gameOver()
函数时,它将擦除屏幕。这是gameOver()
函数:function gameOver() {
ctx.font = "60px monospace";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText("Game Over", width/2, height/2);
clearTimeout(timeoutID);
};
我想知道是否有一种方法可以在游戏结束时停止
gameLoop()
功能,而不会收到错误消息且不会擦除屏幕。我尝试了几种不同的方法都没有用。谢谢。 最佳答案
您需要在timeoutID
之外定义gameLoop
,以便在其他位置可见,例如gameOver
函数:
var timeoutID;
function gameLoop() {
// ...
timeoutID = setTimeout( ...
// ...
}
// ...
function gameOver() {
// referencing timeoutID here will now be possible
但是在这种情况下,与保存timeoutID相比,您可能会发现,简单地使用一个外部布尔值指示
gameLoop
是否应该运行,会容易一些:var gameIsOver = false;
function gameLoop() {
if (gameIsOver) return;
// ...
}
// ...
function gameOver() {
gameIsOver = true;
// ...
关于javascript - 如何在多个作用域中定义timeoutId,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51014207/