我正在为android制作一个2d侧滚游戏,并考虑使用box2d进行物理。我想知道在使用box2d时,如果设备的帧速率从60 fps(android的cap)下降到30 fps,那么所有的物理性能都会随之降低吗?
详细说明一下,我将使用实时在线多人游戏,因此帧速率不能作为一个常数。因此,如果多人游戏中的一个设备以每秒60帧的速度运行,而另一个设备以每秒30帧的速度运行,并且一个对象应该以每秒10米的速度移动,那么在速度较慢的设备上,它会以每秒5米的速度移动吗?
我想用box2d,如果是这个问题,有办法解决吗?

最佳答案

你的问题,我想,真的是两个问题。
1)如果在模拟过程中改变物理时间步的速率。
不,你不应该…您可以在游戏循环的a时间步内多次迭代引擎(使用相同的步长值多次调用Step(...)函数)。
从2.3.0 Box2D手册第2.4节:
一个可变的时间步产生可变的结果,这使得
很难调试。所以不要把时间步长和帧速率联系起来
(除非你真的,真的必须这么做)。
2)如何将两个实时物理模拟连接起来,并将它们的物理更新周期相互关联。
很久以前,有一个叫做帝国时代的改变风格的游戏。它拥有数千个人工智能单位在一个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上的弹跳球场中观察特定弹跳球的几个简单测试(例如,iPad2与iPad3的代码完全相同)将显示这一点。在几秒钟的运动之后,错误就慢慢地出现了,突然你的速度/位置变得足够差了。
定点数学是解决这个问题的一种方法,但这种方法也会导致其自身的疯狂。有一次,box2d有一个固定的版本,但这次已经过去了。
我甚至在玩弄box2d的定点版本,但被另一个项目分散了注意力(太空蜘蛛必须死!)有一天…
对于您的特定情况,这可能不是问题(即,您没有进行独立模拟,也没有按预期的方式进行模拟),如果没有,则无需担心。
You can see lots of other Box2D stuff (but not this game...it is not up there yet) here on my blog.
这有用吗?

关于android - Box2D Physics是否依赖于帧速率?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23038132/

10-12 23:39