Javascript 在画布中与requestAnimationFrame一起使用JS倒计时
我正在制作一个简单的画布游戏,我正在使用requestAnimationFrame(Paul Irish的版本)进行gameloop。我在游戏中使用javascript倒计时(显示秒数和100秒数),但它没有以正确的速度倒计时。我知道这与游戏的刷新率有关,因此计数器每帧更新一次,而不是每100秒更新一次。我该如何解决这个问题 下面是计时器对象:Javascript 在画布中与requestAnimationFrame一起使用JS倒计时,javascript,canvas,setinterval,countdown,requestanimationframe,Javascript,Canvas,Setinterval,Countdown,Requestanimationframe,我正在制作一个简单的画布游戏,我正在使用requestAnimationFrame(Paul Irish的版本)进行gameloop。我在游戏中使用javascript倒计时(显示秒数和100秒数),但它没有以正确的速度倒计时。我知道这与游戏的刷新率有关,因此计数器每帧更新一次,而不是每100秒更新一次。我该如何解决这个问题 下面是计时器对象: /** * The timer as an object */ function Timer(position, time) { this.pos
/**
* The timer as an object
*/
function Timer(position, time) {
this.position = position || new Vector(150,210);
this.time = time || 6000;
}
Timer.prototype = {
start: function() {
console.log('start running');
this.initial = this.time; //time in 100'ths of seconds
this.count = this.initial;
this.counter; //10 will run it every 100th of a second
clearInterval(this.counter);
//this.counter = setInterval(this.timer, 10);
this.timer();
},
timer: function() {
//console.log(this.count);
this.count--;
var res = this.count / 100;
//Show counter in canvas
return 'Tid kvar: ' + res.toPrecision(this.count.toString().length) + ' sekunder';
},
draw: function(ct) {
if(this.initial === undefined){this.start();} //Start the timer
ct.save();
if(this.count <=0){ //Remove timer if timer has reached 0
ct.clearRect(this.position.x, this.position.y, Racetrack.innerTrackWidth, Racetrack.innerTrackHeight);
return false;
} else { //draw timer
ct.save();
ct.font = 'bold 3em arial';
ct.fillStyle = 'orange';
ct.fillText(this.timer(), this.position.x, this.position.y);
}
ct.restore();
},
}
我也尝试过将此作为计时器对象,但调试this.count
会显示第一个循环的编号,第二个循环未定义,之后每个循环都显示NaN(我不确定这是否会解决计时问题?)
功能计时器(位置、时间){
this.position=位置| |新向量(150210);
this.time=time | | 6000;
}
Timer.prototype={
开始:函数(){
log('start running');
this.initial=this.time;//以百分之一百秒为单位的时间
this.count=this.initial;
this.counter;//10将每隔100秒运行一次
clearInterval(此计数器);
this.counter=设置间隔(this.timer,10);
这个.timer();
},
计时器:函数(){
console.log(this.count);
这是伯爵;
},
getTime:function(){
var res=此计数/100;
返回'Tid kvar:'+res.toPrecision(this.count.toString().length)+'sekunder';
},
绘图:功能(ct){
如果(this.initial==未定义){this.start();}//启动计时器
ct.save();
if(this.count不确定您是要求以1/100的间隔显示时间,还是使用setInterval时时间不准确
答:setInterval不应用于计时,因为它远远不够精确,而且随着时间间隔的减小,情况会变得更糟,如果正在运行动画,情况会更糟
B:浏览器以1/60秒刷新。您可以强制显示器以1/100秒的速度渲染和显示,但根据图形硬件的不同,它可能永远不会显示,因为此时显示器正在扫描屏幕上其他位置的像素。或者,当您覆盖显示时,您将在图形正在扫描时发生剪切把它放在显示器上
使用requestAnimationFrame获得倒计时的最佳方法
var start = true; // flags that you want the countdown to start
var stopIn = 3000; // how long the timer should run
var stopTime = 0; // used to hold the stop time
var stop = false; // flag to indicate that stop time has been reached
var timeTillStop = 0; // holds the display time
// main update function
function update(timer){
if(start){ // do we need to start the timer
stopTime = timer + stopIn; // yes the set the stoptime
start = false; // clear the start flag
}else{ // waiting for stop
if(timer >= stopTime){ // has stop time been reached?
stop = true; // yes the flag to stop
}
}
timeTillStop = stopTime - timer; // for display of time till stop
// log() should be whatever you use to display the time.
log(Math.floor(timeTillStop / 10) ); // to display in 1/100th seconds
if(!stop){
requestAnimationFrame(update); // continue animation until stop
}
}
requestAnimationFrame(update); // start the animation
忘了加
通过这种方法,你永远无法获得100秒的准确度。你的平均准确度为7-8毫秒。但是,除非你把它变得更复杂,否则这是你能做到的最好的方法。7-8毫秒的平均准确度是恒定的,在2小时1秒内是相同的,只是由大约16毫秒的动画刷新时间决定的。不确定你是否需要这样做ing以1/100的间隔显示时间,或者如果使用setInterval时时间不准确
答:setInterval不应用于计时,因为它远远不够精确,而且随着时间间隔的减小,情况会变得更糟,如果正在运行动画,情况会更糟
B:浏览器以1/60秒刷新。您可以强制显示器以1/100秒的速度渲染和显示,但根据图形硬件的不同,它可能永远不会显示,因为此时显示器正在扫描屏幕上其他位置的像素。或者,当您覆盖显示时,您将在图形正在扫描时发生剪切把它放在显示器上
使用requestAnimationFrame获得倒计时的最佳方法
var start = true; // flags that you want the countdown to start
var stopIn = 3000; // how long the timer should run
var stopTime = 0; // used to hold the stop time
var stop = false; // flag to indicate that stop time has been reached
var timeTillStop = 0; // holds the display time
// main update function
function update(timer){
if(start){ // do we need to start the timer
stopTime = timer + stopIn; // yes the set the stoptime
start = false; // clear the start flag
}else{ // waiting for stop
if(timer >= stopTime){ // has stop time been reached?
stop = true; // yes the flag to stop
}
}
timeTillStop = stopTime - timer; // for display of time till stop
// log() should be whatever you use to display the time.
log(Math.floor(timeTillStop / 10) ); // to display in 1/100th seconds
if(!stop){
requestAnimationFrame(update); // continue animation until stop
}
}
requestAnimationFrame(update); // start the animation
忘了加
通过这种方法,你永远无法获得100秒的精度。你的平均速度为7-8毫秒。但是,除非你将其变得更复杂,否则这是你能做到的最好的方法。7-8毫秒的平均速度是恒定的,在2小时1秒内保持不变,只是由大约16毫秒的动画刷新时间决定。requestAnimationFrame pass将它调用的函数的时间(毫秒)作为第一个参数。function myLoop(time){requestAnimationFrame(myLoop)}
使用setInterval
尤其是使用如此短的时间间隔会带来麻烦,因为任何延迟浏览器1/100秒的操作都会导致浏览器试图跟上,如果您的动画渲染时间接近该时间,则会使浏览器崩溃。避免使用setInterval
进行任何较短的操作han浏览器我的挂起。@Blindman67有没有其他解决方法的建议?requestAnimationFrame将以毫秒为单位的时间传递给它作为第一个参数调用的函数。function myLoop(time){requestAnimationFrame(myLoop)}
使用setInterval
尤其是使用如此短的时间间隔会带来麻烦,因为任何延迟浏览器1/100秒的操作都会导致浏览器试图跟上,如果您的动画渲染时间接近该时间,则会使浏览器崩溃。避免使用setInterval
进行任何较短的操作han我的浏览器挂起了。@Blindman67有什么建议可以用另一种方法解决这个问题吗?谢谢,看起来不错!不过有一个问题:参数计时器做什么?-没有参数发送到函数,但它接受这个参数。它从哪里得到它的值?@Sluggo Time在浏览器调用回调函数时作为参数传递您可以通过requestAnimationFrame
进行设置。这是以1/1000秒为单位的时间,现在大多数浏览器都将其精确到1000000秒,因为额外的精度表示为小数部分,因此100.055的值是100055/1000000秒。时间是页面启动后的时间,但我不知道页面何时开始。通过将其与Date.now()进行比较,可以将其同步到实时
并在页面的生命周期中使用该偏移量。谢谢,看起来不错!但有一个问题:参数计时器做什么?-没有参数发送到函数,但它接受该参数。它从何处获得其值?@Sluggo Time在调用通过requestAnimationFra设置的回调函数时,由浏览器作为参数传递me
。这是千分之一秒的时间,现在大多数浏览器都能精确到百万分之一秒
var start = true; // flags that you want the countdown to start
var stopIn = 3000; // how long the timer should run
var stopTime = 0; // used to hold the stop time
var stop = false; // flag to indicate that stop time has been reached
var timeTillStop = 0; // holds the display time
// main update function
function update(timer){
if(start){ // do we need to start the timer
stopTime = timer + stopIn; // yes the set the stoptime
start = false; // clear the start flag
}else{ // waiting for stop
if(timer >= stopTime){ // has stop time been reached?
stop = true; // yes the flag to stop
}
}
timeTillStop = stopTime - timer; // for display of time till stop
// log() should be whatever you use to display the time.
log(Math.floor(timeTillStop / 10) ); // to display in 1/100th seconds
if(!stop){
requestAnimationFrame(update); // continue animation until stop
}
}
requestAnimationFrame(update); // start the animation