使用Dart更新HTML Canvas

Fde*_*ral 2 oop html5 frame-rate canvas dart

我应该如何使用Dart更新我在HTML中创建的画布,以便我创建的游戏以'x'个FPS运行?

Gam*_*ist 6

要控制游戏的帧速率:

  • 使用requestAnimationFrame(在windowlib中).
  • 测量两次通话之间的时间.
  • 如果实际帧速率太高,则丢帧.
  • 如果自上一帧起经过了太多时间,则只考虑一帧.如果操作系统将游戏标记为/应用程序设置为空闲,则会发生这种情况.

requestAnimationFrame(callback)将在浏览器准备好绘制时立即触发回调.
因此,它将触发屏幕的所有完整fps速率(假设您的绘制/计算不需要花费太多时间).回调需要一个时间参数,根据浏览器,它是高分辨率(Dart VM,Chrome js)或低分辨率(FF,Sf)的当前时间.

您对帧速率的唯一选择是帧速率低于或等于屏幕的帧速率.
因此,如果您想要一个25Hz的屏幕,并且您在50Hz的屏幕上,那么通过将一个帧丢弃到两个以上,您将处于25Hz.精细.
但是如果你在60Hz屏幕上要求25Hz,30 fps仍然太高,所以你大部分时间都会得到15 fps.
(也许一个好主意不是将fps限制为常数,而是计算所需fps所需的比率(> = 100Hz屏幕的1/2或1/3或甚至1/4或更多).

无论如何这里是一个游戏循环,它将控制游戏的fps(具有恒定限制),并且处理游戏时间,意味着游戏所用的时间(如果用户选中,则会与实时不同,这会使requestAnimationFrame停止为以及计时器.):

class Game {

   num gameTime = 0 ; // actual time elapsed within game since game started.

   num minFrameTime = 20 ; // limit to 50 fps. 

   num maxFrameTime = 200 ; // consider game was tabbed out after 200ms

   num get currentFrameRate => (_lastdt == 0) ? -1 : 1000 / _lastdt ;  

   void launchAnimation() {
        window.requestAnimationFrame(_getAnimateTime);     
    }

   void _animate(num animateCallTime) {
       window.requestAnimationFrame(_animate); // keep animating.
       // ---- time handling
       num dt = animateCallTime - _lastAnimateTime ; // time elapsed since last frame.
       if (dt<minFrameTime) return; // frame rate too high, drop this frame.
       if (dt>maxFrameTime) dt = minFrameTime ; // consider just one frame elapsed if game tabbed out.
       gameTime += dt ;
       _lastdt = dt ;
       _lastAnimateTime = animateCallTime ;
       // ---- actual animation 
       // draw :  must be done first (we're on sync with screen)

       // update
   }

   void _getAnimateTime(num animateCallTime) { 
       _lastAnimateTime = animateCallTime ; // now we have start time with right resolution
       window.requestAnimationFrame(_animate); // start animating
   }

   num _lastAnimateTime = 0;

   num _lastdt = 0; // last valid frame duration.
 }
Run Code Online (Sandbox Code Playgroud)

Rq:我建议桌面限制为60 fps,移动设备限制为30 fps.
Rq2:上面的代码实际上是我使用的游戏循环的精简版,就像3倍大,可以解决动画循环的"所有"问题(所有......或者至少我看到的那些: - )).