2.4 模拟(Box2D 的)世界
我们已经初始化好了地面盒和一个动态盒。现在是让牛顿接手的时刻了。我们只有少数几个问
题需要
考虑。
Box2D 中有一些数学代码构成的
积分器
(integrator),积分器在离散的时间点上模拟物理方程,它将
与游戏动画循环一同运行。所以我们需要为 Box2D 选取一个时间步,通常来说游戏物理引擎需
要至少
60Hz 的速度,也就是 1/60 的时间步。你可以使用更大的时间步,但是你必须更加小心地为你
的世界调
整定义。我们也不喜欢时间步变化得太大,所以不要把时间步关联到帧频(除非你真的必须这样
做)。直截
了当地,这个就是时间步:
float32 timeStep = 1.0f / 60.0f;
除了积分器之外,Box2D 中还有
约束求解器
(constraint solver)。约束求解器用于解决模拟中的所有
约束,一次一个。单个的约束会被完美的求解,然而当我们求解一个约束的时候,我们就会稍
微耽误另
一个。要得到良好的解,我们需要迭代所有约束多次。建议的 Box2D 迭代次数是 10 次。你可
以按自己
的喜好去调整这个数,但要记得它是速度与质量之间的平衡。更少的迭代会增加性能并降低精
度,同样
地,更多的迭代会减少性能但提高模拟质量。这是我们选择的迭代次数:
Page 5
int32 iterations = 10;
注意时间步和迭代数是完全无关的。一个迭代并不是一个子步。一次迭代就是在时间步之中的
单次遍
历所有约束,你可以在单个时间步内多次遍历约束。
现在我们可以开始模拟循环了,在游戏中模拟循环应该并入游戏循环。每次循环你都应该调用
b2World::Step,通常调用一次就够了,这取决于帧频以及物理时间步。
这个 Hello World 程序设计得非常简单,所以它没有图形输出。胜于完全没有输出,代码会打
印出动
态物体的位置以及旋转角度。Yay!这就是模拟 1 秒钟内 60 个时间步的循环:
for (int32 i = 0; i < 60; ++i)
{
world.Step(timeStep, iterations);
b2Vec2 position = body->GetPosition();
float32 angle = body->GetAngle();
printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);
评论3
最新资源