似乎我在cancelAnimationFrame和clearTimeout之间迷失了自己。不知道如何阻止Snake游戏。这是我的代码片段,它开始动画:
window.addEventListener( "load", function gameLoop() {
globalTimer = setTimeout( function() {
snakeObj.update();
requestAnimationFrame( gameLoop );
}, 100 );
});
通过这种方式我试图阻止我的游戏:
if ( parseInt(this.snakeHead.style.top) == fieldObj.h ||
parseInt(this.snakeHead.style.left) == fieldObj.w ) {
gameObj.stopGame();// stop game message
clearTimeout(globalTimer);
}
但它不起作用 - 停止显示游戏消息,但动画仍在继续。
这里是我的所有代码:
// field object
var globalTimer;
var fieldObj = {
field: document.getElementById( "field" ),
w: 480,
h: 580
},
gameObj = {
pastCoord: [],
getRandomCoord: function( num ) { // 20 is width of one body segment
return Math.round( Math.floor(( Math.random() * num)) / 20 ) * 20;
},
createSnakeTarget: function() {
var t = document.createElement( "div" );
t.id = "snake-target";
t.style.top = this.getRandomCoord( fieldObj.h ) + "px";
t.style.left = this.getRandomCoord( fieldObj.w ) + "px";
fieldObj.field.appendChild( t );
},
stopGame: function() {
var stopMessage = document.createElement("div");
stopMessage.className = "stop-message";
stopMessage.style.background = "white";
fieldObj.field.appendChild( stopMessage );
//TODO: write message to stopGame
}
};
gameObj.createSnakeTarget();
// snake object
snakeObj = {
snakeHead: document.getElementById("head"),
snakeBody: document.getElementsByClassName( "snake-body" ),// there must be one element
p: {
x: 0, // position x
y: 0 // position y
},
v: {
x: 20, // velocity ( one loop move one unit of snake body)
y: 20
},
keys: {
up: null,
l: null,
r: null,
down: null
},
stepInSnakeBody: 0,// go through snakeBody
stepInPastCoord: 0,// go through pastCoord
addBodySegment: function() {
var seg = document.createElement( "div" );
seg.className = "snake-body";
fieldObj.field.appendChild( seg );
seg.style.top = this.p.x + "px";// receive current position
seg.style.left = this.p.y + "px";
},
update: function() {
var snakeTarget = document.getElementById("snake-target");
if ( this.keys.down ) {
this.p.x += this.v.x;
} else if ( this.keys.up ) {
this.p.x -= this.v.x;
} else if ( this.keys.r ) {
this.p.y += this.v.y;
}else if ( this.keys.l ) {
this.p.y -= this.v.y;
}
this.snakeHead.style.top = this.p.x + "px";
this.snakeHead.style.left = this.p.y + "px";
gameObj.pastCoord.push([this.p.x, this.p.y]);// create and push coord of snake head
//every step index in snakeBody receive coords from pastCoord
this.snakeBody[this.stepInSnakeBody].style.top = gameObj.pastCoord[this.stepInPastCoord][0] + "px";
this.snakeBody[this.stepInSnakeBody].style.left = gameObj.pastCoord[this.stepInPastCoord][1] + "px";
this.stepInSnakeBody++; // increment index every step
this.stepInPastCoord++;
if ( this.stepInSnakeBody === this.snakeBody.length ) {
this.stepInSnakeBody = 0; // when stepInSnakeBody equal length of snake go to zero
//and apply coords
}
// detect collision with target
if ( this.snakeHead.style.top === snakeTarget.style.top &&
this.snakeHead.style.left === snakeTarget.style.left ) {
fieldObj.field.removeChild( snakeTarget );
gameObj.createSnakeTarget();
snakeObj.addBodySegment();
}
if ( parseInt(this.snakeHead.style.top) == fieldObj.h ||
parseInt(this.snakeHead.style.left) == fieldObj.w ) {
gameObj.stopGame();
clearTimeout(globalTimer);
}
}
};
// Crome works only with keydown and keyup
window.addEventListener('keydown', function() {
// before changing direction you have to put previous direction to false
if ( event.keyCode == 38 ) {
snakeObj.keys.up = true;
snakeObj.keys.down = false;
} else if ( event.keyCode == 40 ) {
snakeObj.keys.down = true;
snakeObj.keys.up = false;
} else if ( event.keyCode == 39 ) {
snakeObj.keys.r = true;
snakeObj.keys.up = false;
snakeObj.keys.down = false;
} else if ( event.keyCode == 37 ) {
snakeObj.keys.l = true;
snakeObj.keys.r = false;
snakeObj.keys.up = false;
snakeObj.keys.down = false;
}
}, false);
//TODO: add event hendler to click to some button
window.addEventListener( "load", function gameLoop() {
globalTimer = setTimeout( function() {
snakeObj.update();
requestAnimationFrame( gameLoop );
}, 100 );
});
这里是codepen(仅在CHROME中工作)http://codepen.io/Kuzyo/pen/pamzC
谢谢你的帮助。
答案 0 :(得分:1)
您需要致电cancelAnimationFrame
。
但是,您需要确保在 requestAnimationFrame
之前致电update
。目前您正在呼叫stopGame
,但在stopGame
/ update
完成后,requestAnimationFrame
会安排另一个循环,即使您的stopGame
呼叫cancelAnimationFrame
它不会停止动画。
另一种方法是使用您在gameLoop
函数中检查的布尔标志。