我应该如何更新我在 HTML 中创建的 Canvas 使用 Dart 以便我正在创建的游戏运行 “x”个 FPS?
最佳答案
控制游戏的帧率:
- 使用
requestAnimationFrame
(在window
库中)。 - 测量两次通话之间的时间。
- 如果实际帧速率太高则丢弃帧。
- 如果自上一帧以来经过了太多时间,则考虑只经过一帧。如果游戏被操作系统选中/应用程序设置为空闲,就会发生这种情况。
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.
}
Rq:我建议将桌面限制为 60 fps,移动限制为 30 fps。
Rq2:上面的代码实际上是我使用的游戏循环的精简版本,大约大了 3 倍,用于解决动画循环的“所有”问题(所有......或者至少是我看到的那些:- )).
关于html - 使用 Dart 更新 HTML Canvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21801249/