Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/457.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在多个作用域中定义timeoutId_Javascript_Canvas - Fatal编程技术网

Javascript 如何在多个作用域中定义timeoutId

Javascript 如何在多个作用域中定义timeoutId,javascript,canvas,Javascript,Canvas,我已经使用javascript画布制作了一个经典的蛇街机游戏,我正在尝试内置功能来减少游戏动画运行的间隔。如果你不熟悉蛇,一条蛇会在屏幕上四处移动,试图吃掉随机出现的苹果,同时尽量避免撞到自己或墙壁上。每一次蛇吃一个苹果,它的大小就会变长,游戏也就变得更难了。每次蛇吃苹果时,我都会加快游戏的速度,以增加游戏的难度。我在下面的代码片段中实现了这一点: //Animate the game function gameLoop() { ctx.clearRect(0, 0, width, heig

我已经使用javascript画布制作了一个经典的蛇街机游戏,我正在尝试内置功能来减少游戏动画运行的间隔。如果你不熟悉蛇,一条蛇会在屏幕上四处移动,试图吃掉随机出现的苹果,同时尽量避免撞到自己或墙壁上。每一次蛇吃一个苹果,它的大小就会变长,游戏也就变得更难了。每次蛇吃苹果时,我都会加快游戏的速度,以增加游戏的难度。我在下面的代码片段中实现了这一点:

//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()
函数,它访问运行游戏的
setTimeout
函数的
timeoutId
,但是
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);
};
var timeoutID;
function gameLoop() {
  // ...
  timeoutID = setTimeout( ...
  // ...
}
// ...
function gameOver() {
  // referencing timeoutID here will now be possible

我想知道是否有一种方法可以在游戏结束时停止
gameLoop()
功能,而不会收到错误消息,也不会擦除屏幕。我试过几种不同的方法,但都没有用。谢谢。

您需要在
gameLoop
之外定义
timeoutID
,以便它在其他地方可见,例如
gameOver
功能:

function gameOver() {
  ctx.font = "60px monospace";
  ctx.fillStyle = "black";
  ctx.textAlign = "center";
  ctx.fillText("Game Over", width/2, height/2);
  clearTimeout(timeoutID);
};
var timeoutID;
function gameLoop() {
  // ...
  timeoutID = setTimeout( ...
  // ...
}
// ...
function gameOver() {
  // referencing timeoutID here will now be possible
但是在这种情况下,您可能会发现简单地使用一个外部布尔值来指示
gameLoop
是否应该运行,而不是保存timeoutID,这会更容易一些:

var gameIsOver = false;
function gameLoop() {
  if (gameIsOver) return;
  // ...
}
// ...
function gameOver() {
  gameIsOver = true;
  // ...

谢谢我曾尝试在全局范围内定义
timeoutID
,但由于某种原因,它以前不起作用。也许我把事情搞砸了,因为这次成功了。非常感谢。