我一直在玩canvas
和动画,专门针对HTML5游戏,并快速了解了仅使用requestAnimationFrame (rFA)
的限制,并转而使用基于时间的动画。
无论显示器刷新率或FPS如何,我都希望保持不变的游戏性,但我不确定如何最好地处理动画。我已经阅读了各种各样的实现,但没有找到任何最佳实践可以这么说。我应该使用两者的组合吗?
到目前为止,我已经考虑了几个选项:
rFa
(在fps更改时更改结果):
var animate = function() {
draw();
requestAnimationFrame(animate);
}
仅基于时间(并非总是一致):
var animate = function() {
now = Date.now();
delta = now - last;
last = now;
draw(delta);
window.setTimeout(animate, 1000/60)
}
使用rFA
在setInterval
上设置FPS(并非总是一致):
setInterval(function () {
draw();
requestAnimationFrame();
}, 1000/fps);
rFA
试图逼迫fps(看起来不是很强大,变量delta会更好):
var delta = 1000 / fps;
var animate = function() {
now = Date.now();
if (now - last >= delta) {
last = now;
}
draw(delta);
requestAnimationFrame(animate);
}
基于时间的rFA
(一些奇怪的结果):
var animate = function () {
now = Date.now();
delta = now - last;
last = now;
draw(delta);
requestAnimationFrame(animate);
}
忽略浏览器支持的缺乏和Date.now()的使用,我只是想展示我的思维流程。我认为最后一个选项是可取的,但最后两个选项可能会遇到更新太多和丢失冲突等问题,以及更新花费太长时间以致动画失去所有控制权。
当用户使用rFA
标签时,只有动画会暂停,使用基于时间的功能调用rFA
意味着游戏/动画将继续在后台运行,这不是理想的
处理动画的最佳方法是什么,试图保持一致的结果,无论fps如何,以上所有可能都很糟糕,我为长篇文章道歉(这是我到目前为止所尝试的并且仍然很丢失)?考虑到上述问题会更好吗?
答案 0 :(得分:1)
如果您有requestAnimationFrame
可用,我就不会反对它,只能从其回调中拨打draw()
。当然,您应该始终使用增量计时。
如果帧速率太低,这里是游戏逻辑更新的raF
的复杂变体,后退到setTimeout
:
var maximalUpdateDelay = 25; // ms
var updateTimeout, now;
function animate() {
updateTimeout = setTimeout(animate, maximalUpdateDelay);
var delta = -now + (now = Date.now());
update(now, delta);
}
function main() {
clearTimeout(updateTimeout);
animate(); // update the scene
draw(); // render the scene
requestAnimationFrame(main);
}
main();
答案 1 :(得分:0)
我建议您查看HTML 5 - Game Development course on Udacity。我不记得从课程中实现这个问题(但肯定有一个),但我从游戏玩法的角度来看,只是使用rAF(就像你的第一个子弹)是最有趣的,即使游戏速度慢因速度较慢的计算机需要处理太多而导致数据丢失。
答案 2 :(得分:0)
我认为你在最后一个方面处于正确的轨道上,因为它应该在不同帧率下运行的设备之间提供最大的一致性,但是如果它太高而无法避免大的话,你肯定想要降低delta值跳转:
var animate = function () {
now = Date.now();
delta = now - last;
last = now;
if(delta > 20) {
delta = 20;
}
draw(delta);
requestAnimationFrame(animate);
};