简体   繁体   中英

Why isn't clearInterval() stopping the setInterval function?

I'm making a snake game and the entire game is ran inside of the runGame() function. I have the function set to repeat every 80ms like this startGame = setInterval(runGame, 80) Then inside of the runGame() function I check for a collision. Inside the the checkForCollision() function I set a timeout to return true after 5 seconds indicating there has been a collision then running the code clearInterval(runGame) this does nothing? Why is that?

 //grab the canvas/set its context/create the snake and its size const cvs = document.querySelector('canvas'); const ctx = cvs.getContext('2d'); const unit = 16; const snake = [ { //set the snakes starting position in the middle of the canvas x: cvs.width/2 - 8, y: cvs.height/2 - 8 } ]; let food = {x: 0, y: 0} let startGame = setInterval(rungame, 80); getFood(); let direction; function rungame() { isRunning = true; draw(snake[0].x, snake[0].y, "limegreen"); document.addEventListener('keydown', (event) => { if(event.keyCode == 37) direction = "left"; else if(event.keyCode == 38) direction = "up"; else if(event.keyCode == 39) direction = "right"; else if(event.keyCode == 40) direction = "down"; }); switch(direction) { case "left": draw(snake[0].x, snake[0].y, "#858585"); snake[0].x -= unit draw(snake[0].x, snake[0].y, "limegreen"); break; case "right": draw(snake[0].x, snake[0].y, "#858585"); snake[0].x += unit draw(snake[0].x, snake[0].y, "limegreen"); break; case "up": draw(snake[0].x, snake[0].y, "#858585"); snake[0].y -= unit draw(snake[0].x, snake[0].y, "limegreen"); break; case "down": draw(snake[0].x, snake[0].y, "#858585"); snake[0].y += unit draw(snake[0].x, snake[0].y, "limegreen"); break; } if(checkForCollision()) clearInterval(startGame); } //--------------------HELPER FUNCTIONS function draw(x, y, color) { for(let i = 0; i < snake.length; i++) { ctx.fillStyle = color; ctx.fillRect(x, y, unit, unit, color); } } function getFood() { let x = Math.floor(Math.random() * cvs.width/unit) * unit; let y = Math.floor(Math.random() * cvs.height/unit) * unit; food.x = x; food.y = y; draw(food.x, food.y, 'red'); } function checkForCollision() { setTimeout(function() { return true; }, 5000) }
 html, body { margin: 0; padding: 0; } body { font-family: 'Odibee Sans'; height: 100vh; display: flex; justify-content: center; background-color: #333; } .wrapper { display: flex; flex-direction: column; justify-content: center; position: relative; top: -27.5px; } canvas { background-color: #858585; } .score { width: 50px; height: 50px; align-self: center; color: white; display: flex; justify-content: center; align-items: center; font-size: 4rem; padding-bottom: 5px; text-shadow: 5px 0px 0px #858585; /* why does align self work here but not justify-content */ }
 <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Snake 2.0</title> <link href="https://fonts.googleapis.com/css?family=Odibee+Sans&display=swap" rel="stylesheet"> <link rel="stylesheet" href="styles.css"> </head> <body> <div class="wrapper"> <div class="score">0</div> <div class="canvas-wrap"> <canvas width="1008" height="528"></canvas> </div> </div> </body> <script src="script.js"></script> </html>

那是因为您的checkForCollision函数返回undefined所以条件永远不会为true ,您只是在计时器内执行该函数,并且返回值永远不会传递给要返回的外部函数。

You cannot return from an async function, the setTimeout is an async function. The checkForCollision function will always return undefined .

Solution:

Return a promise from the checkForCollision function.

function checkForCollision() {
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      resolve(true);
  }, 5000)
  });
}

And wait for the promise to be resolved.

(async function() {
  let  collision = await checkForCollision();
  if(collision);
    clearInterval(startGame);
})();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM