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.