如何将setInterval存为变量并使用clearInterval控制贪吃蛇定时器?
解决贪吃蛇游戏的定时器冲突问题
没问题,这事儿其实很简单——你只需要把定时器的ID存到一个变量里,每次触发右键时先清除旧的定时器,再创建新的就行。我给你一步步讲清楚:
核心思路
每个setInterval调用都会返回一个唯一的定时器ID,把这个ID存在全局变量里,之后用clearInterval(这个ID)就能精准停止对应的定时器。这样就不会出现多个定时器同时跑,导致蛇移动异常的问题了。
修改步骤
- 添加全局定时器变量:在你的全局变量声明区,加一个变量用来存定时器ID,比如
var gameInterval;。 - 右键事件里先清旧定时器:每次按右键时,先检查如果之前有定时器在运行,就清除它,再创建新的定时器并把ID存到变量里。
- (可选)初始化未定义的变量:你的代码里有些变量(比如
snakeX、snakeSpeedX)没初始化,我也一起补上,避免运行报错。
修改后的完整代码
<html> <body> <canvas id="gamecanvas" width="1330" height="625"></canvas> <script> var canvas; var canvasContext; // 新增:全局变量存储定时器ID var gameInterval; // 新增:初始化蛇和画布相关变量(避免运行报错) var snakeX = 100; var snakeY = 100; var snakeSpeedX = 5; var canvasX = 100; var canvasY = 50; window.onload = function () { canvas = document.getElementById("gamecanvas"); canvasContext = canvas.getContext("2d"); } function both() { moveSnake(); drawEvery(); }; function moveSnake() { snakeX = snakeX + snakeSpeedX; if (snakeX + 10 >= 500 + 400) { snakeX = 450; } } window.addEventListener('keydown', changedir, false); function changedir(event) { var code = event.keyCode; //right arrow key if (code == 39) { // 修改:先清除旧的定时器(如果存在) if (gameInterval) { clearInterval(gameInterval); } // 把定时器ID存到变量里 gameInterval = setInterval(both, 1000 / 30); }; } function drawEvery() { canvasContext.fillStyle = "yellow"; canvasContext.fillRect(0, 0, canvas.width, canvas.height); canvasContext.fillStyle = "black"; canvasContext.fillRect(canvasX, canvasY, 500, 500); canvasContext.fillStyle = "red"; canvasContext.fillRect(snakeX, snakeY, 20, 20); canvasContext.fillStyle = "green"; canvasContext.fillRect(500, 200, 20, 20); } </script> </body> </html>
为什么这样有效?
- 每次按右键时,旧的定时器会被
clearInterval停止,然后才启动新的定时器,确保同一时间只有一个定时器在驱动蛇移动和画面绘制。 - 把定时器ID存在全局变量里,是因为需要在
changedir函数和其他可能的地方(比如游戏结束时)都能访问到这个ID来清除定时器。
内容的提问来源于stack exchange,提问作者Prateek Sharma
相关产品推荐
相关产品推荐

