我正在尝试在HTML5画布上构建一个小型游戏,并且尝试在游戏中设置1分钟倒数计时器时遇到了麻烦。
以下代码包含timeKeeper
函数和animate
循环。
function timeKeeper(width, font, posX, posY, text) {
this.width = width;
this.x = posX;
this.y = posY;
this.font = font;
this.text = text;
this.numSeconds = 0;
this.time = 0;
this.draw = () => {
c.font = this.width + " " + this.font;
c.fillStyle = "white";
c.fillText(this.text, this.x, this.y);
}
this.update = () => {
setInterval(() => {
this.text -= 1;
},1000)
this.draw();
}
}
// Animation Loop
function animate() {
requestAnimationFrame(animate)
c.clearRect(0, 0, canvas.width, canvas.height)
timeBoard.update()
//Move enemies
enemies.forEach((enemy) => {
//update score and time
scoreBoard.draw();
//draw labels
scoreLabel.draw();
timeLabel.draw();
//update enemies
enemy.update();
enemy.checkBoundary();
if (enemy.isTrue == true) {
enemies.splice(enemies.indexOf(enemy), 1);
// console.log(enemies);
}
if (enemies.length == 0) {
setTimeout(initEnemies(), 200)
}
//collision detection by checking color
if (enemy.color == "#2185C5") {
if (getDistance(enemy.x, enemy.y, ship[0].x, ship[0].y) < enemy.radius + ship[0].radius) {
enemy.color = "#FF00FF"
scoreBoard.update();
}
}
});
//create one particle
ship[0].update();
}
我认为这里发生的是timeBoard.update()
函数在每一帧都被调用,从而导致倒数真的很快。
有人可以帮我解决这个问题吗?
先谢谢了。
答案 0 :(得分:1)
您需要让计数器在动画帧循环方法之外运行。您可以在函数内添加某种计时器来补偿帧(60fps意味着animate()
大约每隔16.667ms运行一次),但是requestAnimationFrame()
并不总是以60fps运行。如果浏览器无法以这种速度渲染,则会降低帧循环的速度。因此,制作与requestAnimationFrame();
完全相关的计时器不是一个好主意。
相反,在函数外添加一个计数器。理想情况下,请在开始动画循环之前立即使用setInterval()
。时间间隔可能看起来像这样。...
var counter = 0;
var timer = window.requestAnimationFrame(function(){
timeBoard.update();
if(counter+1 == 60){
//a minute has passed, clear the interval:
clearInterval(timer);
}else{
counter++;
}
},1000);
如果您在问题详细信息中包含启动动画循环的代码,我可以帮助您确切地说明如何实现它。另外,您没有提及是否需要计数器可重复使用。这些都是要考虑的事情。如果需要可重用,则可以考虑使用面向对象的解决方案。
答案 1 :(得分:1)
setInterval
函数堆栈,这意味着它将继续创建setInterval
实例。通过重复调用timeBoard.update(),您将创建许多setInterval实例,从而使计时器运行得更快。您可以将update
方法更改为类似init
的方法,然后在动画循环之外调用该方法。
答案 2 :(得分:0)
在动画循环中称为timeBoard.draw()
,以便绘制计时器。然后在动画循环外调用setInterval()
函数。
谢谢大家〜:)
function animate() {
requestAnimationFrame(animate)
c.clearRect(0, 0, canvas.width, canvas.height)
timeBoard.draw()
//Move enemies
enemies.forEach((enemy) => {
//update score and time
scoreBoard.draw();
//draw labels
scoreLabel.draw();
timeLabel.draw();
//update enemies
enemy.update();
enemy.checkBoundary();
if (enemy.isTrue == true) {
enemies.splice(enemies.indexOf(enemy), 1);
// console.log(enemies);
}
if (enemies.length == 0) {
setTimeout(initEnemies(), 200)
}
//collision detection by checking color
if (enemy.color == "#2185C5") {
if (getDistance(enemy.x, enemy.y, ship[0].x, ship[0].y) < enemy.radius + ship[0].radius) {
enemy.color = "#FF00FF"
scoreBoard.update();
}
}
});
//create one particle
ship[0].update();
}
//Run Timer
setInterval(() => {
timeBoard.update()
}, 1000)