我用HTML5和Javascript创建了一个简单的蛇游戏。我添加了一个按钮来启动/暂停游戏。但是问题在于,每当我暂停并通过单击按钮开始游戏时,蛇的速度就会增加。我是javascript新手。所以我不确切知道setinterval函数是如何工作的。代码如下:
snake.html
<!DOCTYPE html>
<html>
<head>
<title>Snake game</title>
<style type="text/css">
#snakeBoard {
background-color: black;
}
#score {
text-align: left;
font-size: 40px;
font-family: 'Arial', 'Helvetica', sans-serif;
}
</style>
</head>
<body>
<div id="score">0</div>
<canvas id="snakeBoard" width="250" height="250"></canvas>
<script type="text/javascript" src="snake.js"></script>
<div><button type="submit" id="play" onclick="javascript:game();">Play</button></div>
</body>
</html>
snake.js
var play = document.getElementById("play");
var isPaused = false;
function game() {
setInterval(draw,200);
isPaused = !isPaused;
}
var canvas = document.getElementById("snakeBoard");
var cxt = canvas.getContext("2d");
var canvasW = canvas.width;
var canvasH = canvas.height;
var snakeW = 10;
var snakeH = 10;
var score = 0;
// deafult direction
var direction = "right";
//to color snake
function drawSnake (x, y) {
cxt.fillStyle = "#FFF";
cxt.fillRect(x*snakeW,y*snakeH,snakeW,snakeH);
cxt.strokeStyle = "#000";
cxt.strokeRect(x*snakeW,y*snakeH,snakeW,snakeH);
}
//drawSnake(4,4);
//create snake as array. By default contains four cells
var len = 4;
var snake = [];
for(var i = len-1; i>=0; i--) {
snake.push({x:i, y:0});
}
//create food
food = {
x: Math.round(Math.random()*(canvasW/snakeW-2)+1),
y: Math.round(Math.random()*(canvasH/snakeH-2)+1)
};
function createFood (x,y) {
for (var i=0; i<snake.length; i++) {
if (x==snake[i].x && y==snake[i].y) {
food = {
x: Math.round(Math.random()*(canvasW/snakeW-2)+1),
y: Math.round(Math.random()*(canvasH/snakeH-2)+1)
};
createFood(food.x, food.y);
}
}
cxt.fillStyle = "red";
cxt.fillRect(x*snakeW,y*snakeH,snakeW,snakeH);
cxt.strokeStyle = "#000";
cxt.strokeRect(x*snakeW,y*snakeH,snakeW,snakeH);
}
//add user inputs
document.addEventListener("keydown",getDirection);
function getDirection(e) {
if (e.keyCode == 37 && direction != "right") {
direction = "left";
} else if (e.keyCode == 38 && direction != "down") {
direction = "up";
} else if (e.keyCode == 39 && direction != "left") {
direction = "right";
} else if (e.keyCode == 40 && direction != "up") {
direction = "down";
}
}
// check when the snake hits itself
function checkSelfHit(x,y,snakeArray) {
// for(var i=0; i<snakeArray.length-2; i++) {
// if(snakeArray[snakeArray.length-1].x==snakeArray[i].x && snakeArray[snakeArray.length-1].y==snakeArray[i].y) {
// return true;
// }
// return false;
// }
for (var i=0; i<snakeArray.length; i++) {
if(x==snakeArray[i].x && y==snakeArray[i].y) {
return true;
}
}
return false;
}
// function drawScore(score) {
// cxt.fillStyle = "blue";
// cxt.fillText("Score: ",10,50);
// }
function draw() {
if (isPaused) {
return;
}
cxt.clearRect(0,0,canvasW,canvasH);
for(var i=0; i<snake.length; i++) {
var x = snake[i].x;
var y = snake[i].y;
drawSnake(x,y);
}
createFood(food.x, food.y);
// snake head
let snakeX = snake[0].x;
let snakeY = snake[0].y;
if (direction == "left") snakeX--;
else if (direction == "up") snakeY--;
else if (direction == "right") snakeX++;
else if (direction == "down") snakeY++;
// if the snake hits the wall....... and for self hit checkSelfHit(snakeX,snakeY,snake)
if (snakeX < 0 || snakeY < 0 || snakeX >= canvasW/snakeW || snakeY >= canvasH/snakeH || checkSelfHit(snakeX,snakeY,snake)) {
return;
}
if (snakeX == food.x && snakeY == food.y) {
let newHead = {x: snakeX, y: snakeY};
snake.unshift(newHead);
score++;
food = {
x: Math.round(Math.random()*(canvasW/snakeW-2)+1),
y: Math.round(Math.random()*(canvasH/snakeH-2)+1)
}
}
else {
// remove tail
snake.pop();
let newHead = {x: snakeX, y: snakeY};
snake.unshift(newHead);
}
document.getElementById('score').innerHTML = score;
}
这也是我的第一个游戏项目和第一个javascript项目。因此,感谢任何其他输入或代码错误。 注意:请忽略js文件中的一些注释。那是我的错误。供我参考。
答案 0 :(得分:3)
由于@fredrik已经设置,因此每次执行game
时都会创建一个新间隔
一种方法是通过将时间间隔保存在variabel中并在创建新的间隔之前清除它来控制时间间隔:
var play = document.getElementById("play");
var isPaused = false;
var ticker = null;
function game() {
if (ticker) {
clearInterval(ticker);
ticker = null;
} else {
ticker = setInterval(draw,200);
}
// isPaused = !isPaused; No need for this anymore
}
// ....
另一种方法是让isPaused
完成所有工作,例如:
var play = document.getElementById("play");
var isPaused = true; // should be paused before clicking “play” in this case
var ticker = setInterval(draw,200);
function game() {
isPaused = !isPaused;
}
// ....