是否Box2D的物理依靠帧率? [英] Does Box2D Physics rely on the framerate?

查看:657
本文介绍了是否Box2D的物理依靠帧率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Android一个2D的sidescroller游戏,并正在考虑使用的Box2D的物理学。我想知道,如果使用Box2D的时候,如果设备的帧率从60帧(Android的上限)下降,例如,每秒30帧都将物理学与它慢下来?

要详细说明,我将使用实时在线多人游戏等帧率不能在一个恒定的依据。因此,如果在多人游戏中的设备之一是在60帧运行,并且另一个是在每秒30帧和一个对象应该以10米移动/秒将它在5米较慢设备上的移动/秒

我想用Box2D的,所以如果这个问题是这样的话,有没有变通的办法?


解决方案

您的问题是,我觉得,真是两个问题。

1)如果你在模拟过程中会发生变化的物理时间步的速率。

NO,你不应该。。您可以在游戏循环的时间步多次循环发动机(也称步骤(...)函数多次使用相同的步长值)。

从2.3.0的Box2D手册的第2.4节:


  

一个可变时间步骤产生不同的结果,这使得它
  难以调试。所以不要时间步长系在你的帧速率
  (除非你真的,真的要)。


2)我如何可以连接两个实时物理模拟和奴隶他们的物理更新周期给对方。

曾几何时,有一个叫做帝国时代风格,改变比赛。它吹嘘成千上万的AI战斗单位在近实时的相互28.8网络。它的工作这么好,有人写了关于他们是如何做的文章:


  1. 文章。

  2. 文章的PDF版本。

我适应技术和低于我的更新循环,这样我可以控制的两场比赛在两个不同的iPad运行对对方的帧速率code。

 无效游戏管理:: UpdateGame()
{
   常量UINT32 MAXIMUM_FRAME_RATE =常量:: DEFAULT_OBJECT_CYCLES_PER_SECOND();
   常量UINT32 MINIMUM_FRAME_RATE = 10;
   常量UINT32 MAXIMUM_CYCLES_PER_FRAME =(MAXIMUM_FRAME_RATE / MINIMUM_FRAME_RATE);
   常量双更新周期=(1.0 / MAXIMUM_FRAME_RATE);   静态双lastFrameTime = 0.0;
   静态双cyclesLeftOver = 0.0;   双currentTime的;
   双updateIterations;   currentTime的= CACurrentMediaTime();
   updateIterations =((currentTime的 - lastFrameTime)+ cyclesLeftOver);   如果(updateIterations>(MAXIMUM_CYCLES_PER_FRAME *更新周期))
   {
      updateIterations = MAXIMUM_CYCLES_PER_FRAME *更新周期;
   }   而(updateIterations>更新周期=)
   {
      // DebugLogCPP(帧运行);
      updateIterations - =更新周期;
      //设置此周期的随机种子。
      RanNumGen ::的setSeed(_cycleManager-> GetObjectCycle());
      //调度消息。
      _messageManager-> SendMessages();
      //更新所有实体。
      _entityManager->更新();
      //更新物理
      _gameWorldManager->更新(常量:: DEFAULT_OBJECT_CYCLE_SECONDS());
      //推进循环时钟。
      _cycleManager->更新();
   }   cyclesLeftOver = updateIterations;
   lastFrameTime = currentTime的;
}

此片$ C $的c保持上下最大值之间执行均衡的迭代次数。一个关键件需要注意的是,如果没有及时收到了来自其他玩家的消息,该功能的实际调用不会发生。这有效地奴两个物理系统连接在一起。

3)的一部分时(也许)真的应该知道

如果你打算使用两台设备上Box2D的独立运行的物理,你将几乎肯定会看到他们在短时间后发散。我跑在iPad 2和iPad 3我的比赛,他们分道扬镳了几秒钟(冲突发生在一个,而不是其他)后发现。这是因为在浮点数四舍五入行为基于多种因素是不同的。对于几个简单的计算,没有任何问题。但小的差异潜入低阶位和积累,当值不断通过循环集成商(如你会看到,例如,在物理模拟)。双precision帮助了一点,但不到底。

在多个CPU上弹跳球(例如iPad 2的对比的iPad 3完全相同的code)的领域寻找一个特定的反弹球,一些简单的测试将显示出这一点。错误动作几秒钟,突然你的速度后,蠕变/位置偏移足以有所作为。

定点数学是一个解决方案,但这种方式也导致了其自身的那种疯狂。在一个点上,Box2D的有一个固定点的版本,但这个时代已经过去了。

我甚至炮制的Box2D的固定点的版本玩弄,却得到了另一个项目分心(太空蜘蛛必须死!)。有一天...

这可能不适合你的特殊情况的问题(即你没有做独立的模拟或一种方式,它按预期工作做),如果实在不行,没有后顾之忧。

你可以看到很多其他的东西Box2D的(但不是这个游戏...这是不是在那里还)在这里我博客。

对您有帮助?

I am making a 2D sidescroller game for Android and am thinking of using Box2D for the physics. I would like to know if when using Box2D, if the framerate of the device drops from 60 fps (Android's cap) to, for example, 30 fps will all the physics slow down with it?

To elaborate, I'm going to be using real-time online multiplayer and so the framerate cannot be relied upon as a constant. So if one of the devices in the multiplayer game is running at 60 fps and another is at 30 fps and an object should be moving at 10 metres/second will it move at 5 metres/second on the slower device?

I would like to use Box2D, so if this problem is the case, is there a way around it?

解决方案

Your question is, I think, really two questions.

1) Should you vary the rate of the physics timestep during simulation.

NO, you should not.. You can iterate the engine multiple times during the a time step of the game loop (call the Step(...) function multiple times with the same step values).

From section 2.4 of the 2.3.0 Box2D manual:

A variable time step produces variable results, which makes it difficult to debug. So don't tie the time step to your frame rate (unless you really, really have to).

2) How can I connect two real-time physics simulations and slave their physics update cycles to each other.

Once upon a time there was a genre-altering game called Age of Empires. It boasted thousands of AI units fighting each other in near-real-time on a 28.8 network. It worked so well, somebody wrote an article about how they did it:

  1. The article.
  2. The pdf version of the article.

I adapted the technique and the code below for my update loop so that I could control the frame rate of two games running against each other on two different iPads.

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;
}

This piece of code keeps the number of iterations executed balanced between an upper and lower maximum. One key piece to note is that the actual call to this function doesn't happen if the message from the other player has not been received in a timely fashion. This effectively slaves the two physics systems together.

3) THE PART THAT YOU (MAYBE) REALLY SHOULD KNOW

If you plan on using Box2D on both devices to independently run the physics, you are going to almost certainly going to see them diverge after a short time. I ran my game on an iPad 2 and iPad 3 and noticed after a few seconds they diverged (collisions occur in one, but not the other). This is because rounding behavior in floating point numbers is different based on multiple factors. For a few quick calculations, no problems. But small discrepancies creep into the lower order bits and accumulate when the values are continually cycled through integrators (as you would see, for example, in a physics simulation). Double precision helps a little, but not in the end.

A few simple tests of looking at a specific bouncing ball in a field of bouncing balls on multiple CPUs (e.g. iPad 2 vs. iPad 3 for the exact same code) will show this. The errors creep in after a couple seconds of motion and suddenly your velocities/positions are off enough to make a difference.

Fixed point math is a solution to this, but this way also leads to its own kind of madness. At one point, Box2D had a fixed point version, but this time has passed.

I even toyed with cooking up a fixed point version of Box2D, but got distracted by another project (Space Spiders Must Die!). Some day...

This may not be a problem for your particular situation (i.e. you are not doing independent simulation or doing it in a way that it works as expected), and if it is not, no worries.

You can see lots of other Box2D stuff (but not this game...it is not up there yet) here on my blog.

Was this helpful?

这篇关于是否Box2D的物理依靠帧率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆