我认为你的问题实际上是两个问题。
1) 您是否应该在模拟过程中改变物理时间步的速率。
不,你不应该这样做。。您可以在游戏循环的一个时间步长内多次迭代引擎(使用相同的步长值多次调用Step(...) 函数)。
来自 2.3.0 Box2D 手册的第 2.4 节:
可变的时间步长产生可变的结果,这使得它
难以调试。所以不要将时间步与你的帧速率联系起来
(除非你真的,真的必须)。
2) 我如何连接两个实时物理模拟并将它们的物理更新周期相互从属。
曾几何时,有一款名为《帝国时代》的改变类型的游戏。它拥有数千个 AI 单元在 28.8 网络上近乎实时地相互战斗。效果很好,有人写了一篇关于他们是如何做到的:
- The article.
- The pdf version of the article.
我为我的更新循环调整了以下技术和代码,以便我可以控制在两个不同 iPad 上相互运行的两个游戏的帧速率。
void GameManager::UpdateGame()
{
const uint32 MAXIMUM_FRAME_RATE = Constants::DEFAULT_OBJECT_CYCLES_PER_SECOND();
const uint32 MINIMUM_FRAME_RATE = 10;
const uint32 MAXIMUM_CYCLES_PER_FRAME = (MAXIMUM_FRAME_RATE/MINIMUM_FRAME_RATE);
const double UPDATE_INTERVAL = (1.0/MAXIMUM_FRAME_RATE);
static double lastFrameTime = 0.0;
static double cyclesLeftOver = 0.0;
double currentTime;
double updateIterations;
currentTime = CACurrentMediaTime();
updateIterations = ((currentTime - lastFrameTime) + cyclesLeftOver);
if(updateIterations > (MAXIMUM_CYCLES_PER_FRAME*UPDATE_INTERVAL))
{
updateIterations = MAXIMUM_CYCLES_PER_FRAME*UPDATE_INTERVAL;
}
while (updateIterations >= UPDATE_INTERVAL)
{
// DebugLogCPP("Frame Running");
updateIterations -= UPDATE_INTERVAL;
// Set the random seed for this cycle.
RanNumGen::SetSeed(_cycleManager->GetObjectCycle());
// Dispatch messages.
_messageManager->SendMessages();
// Update all entities.
_entityManager->Update();
// Update the physics
_gameWorldManager->Update(Constants::DEFAULT_OBJECT_CYCLE_SECONDS());
// Advance the cycle clock.
_cycleManager->Update();
}
cyclesLeftOver = updateIterations;
lastFrameTime = currentTime;
}
这段代码使执行的迭代次数在上限和下限之间保持平衡。需要注意的一个关键点是,如果没有及时收到来自其他玩家的消息,则不会发生对该函数的实际调用。这有效地将两个物理系统从属在一起。
3) 您(可能)真正应该知道的部分
如果您计划在两个设备上使用 Box2D 来独立运行物理,您几乎肯定会在短时间内看到它们出现分歧。我在 iPad 2 和 iPad 3 上运行我的游戏,并在几秒钟后注意到它们出现了分歧(碰撞发生在一个,但不是另一个)。这是因为浮点数的舍入行为因多个因素而异。对于一些快速计算,没有问题。但是,当值在积分器中不断循环时,小的差异会蔓延到低位并累积(例如,在物理模拟中)。双精度有一点帮助,但最终没有帮助。
在多个 CPU 上的弹跳球场中查看特定弹跳球的一些简单测试(例如,完全相同的代码的 iPad 2 与 iPad 3)将显示这一点。几秒钟的运动后,错误就会蔓延,突然间你的速度/位置就足够了,足以产生影响。
定点数学是解决此问题的方法,但这种方式也会导致其自身的疯狂。 Box2D曾经有一个定点版本,但这一次已经过去了。
我什至玩弄了一个 Box2D 的定点版本,但被另一个项目(太空蜘蛛必须死!)分心。总有一天……
这对于您的特定情况可能不是问题(即您没有进行独立模拟或以预期的方式进行模拟),如果不是,请不要担心。
You can see lots of other Box2D stuff (but not this game...it is not up there yet) here on my blog.
这有帮助吗?