我将 Box2D 与 WebGL 一起使用。Box2D 需要恒定的帧速率(“世界”更新的时间步长)。
function update(time) {//update of box2d world
world.Step(
1/60 // 1 / frame-rate
, 3 //velocity iterations
, 8 //position iterations
);
但我已经读过定义如下的 requestAnimFrame 是正确的方法。
requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
window.setTimeout(callback, 1000/60);
};
})();
requestAnimFrame 没有给我一个恒定的帧速率,所以我的 Box2D 的变量是不同步的。
有解决办法吗?
[编辑]
实施时约翰(Cutch)的解决方案如下所示:
function interpolate(dt) {
var t = dt/time_step;
body_coordinates = (1-t) * body_coordinates + t * next_body_coordinates;
}
var physicsDt = 0;
function tick() {
var time_now = new Date().getTime();
var dt = time_now - last_time; //Note that last_time is initialized priorly
last_time = time_now;
physicsDt += dt;
clear_the_screen();
requestAnimFrame(tick);
drawEverything();
if(physicsDt >= time_step) {
update();
physicsDt -= time_step;
}
interpolate(dt);
}
请注意,我的物理更新函数负责next_attribue
设置 s。而且,update
在此之前调用了一个物理,以使物理世界领先一帧。
结果
动画相当流畅,除了那些我可以看到一些非常糟糕的跳跃和随机出现的微动的时候。
我认为解决方案中没有解决以下问题:
----> 1) dt
可能会变得大于time_step
:这将dt/time_step
大于 1,这会破坏插值方程。
当dt
仍然大于time_step
一致时,问题会增加。是否有可能克服时间间隔变大的问题time_step
?
我的意思是,即使我们将世界保持在渲染之前一帧,如果时间间隔始终大于time_step
,那么“提前”帧也不会花费很长时间。
----> 2) 想象dt
不到time_step
1 毫秒。然后,世界不会更新那一次。现在插值完成并找到了近似位置(比它应该在的位置晚 1 毫秒)。
可以说下一次dt
和之间没有区别time_step
。
现在,考虑到这一点,没有进行插值dt
并且time_step
是相等的。那么,下一个绘制的是世界上的“前方”框架,对吗?(使用这些方程,用t = 1
)
但准确地说,渲染的世界应该是它之前的 1 毫秒。我的意思是,它落后于世界框架的 1ms 不应该消失。但是用t = 1
, 绘制物理世界框架并忘记了 1ms。
我对代码或以上两点有误吗?
我请求你澄清这些问题。
[编辑]
我在那里的评论中询问了这个网页的作者,寻找一种有效地绘制许多形状的方法。
我学会了这样做:我 bufferData
通过为每个形状保存单独的缓冲区来保存调用,并且createBuffer
在初始化期间只调用一次bindBuffer
。bufferData
每次刷新屏幕时,我都必须遍历所有形状,并且必须在绑定所需形状的缓冲区(使用)之后调用enableVertexAttribArray
和。vertexAttribPointer
bindBuffer
我的形状不会随着时间而改变。它们中只有很多种(如多边形、圆形、三角形)从头到尾都保持不变。