[英]Why isn't clearInterval() stopping the setInterval function?
我正在制作一個蛇游戲,整個游戲都在runGame()
函數內運行。 我將函數設置為每startGame = setInterval(runGame, 80)
重復一次startGame = setInterval(runGame, 80)
然后在runGame()
函數內部檢查碰撞。 在checkForCollision()
函數中,我設置了一個超時以在 5 秒后返回 true 表明發生了碰撞然后運行代碼clearInterval(runGame)
這什么都不做? 這是為什么?
//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
,您只是在計時器內執行該函數,並且返回值永遠不會傳遞給要返回的外部函數。
您不能從async
函數返回, setTimeout
是一個異步函數。 checkForCollision
函數將始終返回undefined
。
解決方案:
從checkForCollision
函數返回一個promise
。
function checkForCollision() {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve(true);
}, 5000)
});
}
並等待承諾得到解決。
(async function() {
let collision = await checkForCollision();
if(collision);
clearInterval(startGame);
})();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.