Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在画布中与requestAnimationFrame一起使用JS倒计时_Javascript_Canvas_Setinterval_Countdown_Requestanimationframe - Fatal编程技术网

Javascript 在画布中与requestAnimationFrame一起使用JS倒计时

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

我正在制作一个简单的画布游戏,我正在使用requestAnimationFrame(Paul Irish的版本)进行gameloop。我在游戏中使用javascript倒计时(显示秒数和100秒数),但它没有以正确的速度倒计时。我知道这与游戏的刷新率有关,因此计数器每帧更新一次,而不是每100秒更新一次。我该如何解决这个问题

下面是计时器对象:

/**
 * 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