Uwa*_*s A 2 android frame-rate box2d game-physics
我正在为 Android 制作 2D 横向卷轴游戏,并考虑使用 Box2D 来实现物理效果。我想知道在使用 Box2D 时,如果设备的帧速率从 60 fps(Android 的上限)下降到例如 30 fps,所有物理效果都会随之减慢吗?
详细来说,我将使用实时在线多人游戏,因此不能将帧速率视为恒定值。因此,如果多人游戏中的一个设备以 60 fps 运行,另一个设备以 30 fps 运行,并且一个物体应以 10 米/秒的速度移动,那么在较慢的设备上它会以 5 米/秒的速度移动吗?
我想使用Box2D,所以如果是这种情况,有办法解决吗?
我认为你的问题实际上是两个问题。
1)是否应该在模拟过程中改变物理时间步长的速率。
不,你不应该。。您可以在游戏循环的一个时间步长期间多次迭代引擎(Step(...)使用相同的步长值多次调用该函数)。
来自 2.3.0 Box2D 手册的 2.4 节:
可变的时间步长会产生不同的结果,这使得调试变得困难。因此,不要将时间步长与帧速率联系起来(除非您真的非常需要)。
2)如何连接两个实时物理模拟并将它们的物理更新周期相互关联。
曾几何时,有一款改变类型的游戏,名为《帝国时代》。它拥有数千个人工智能单元在 28.8 网络上近乎实时地互相战斗。它的效果非常好,有人写了一篇关于他们是如何做到的文章:
我为我的更新循环调整了该技术和下面的代码,以便我可以控制在两台不同 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;
}
Run Code Online (Sandbox Code Playgroud)
这段代码使执行的迭代次数保持在上限和下限之间平衡。需要注意的一个关键问题是,如果没有及时收到来自其他玩家的消息,则不会实际调用此函数。这有效地将两个物理系统结合在一起。
3)你(也许)真正应该知道的部分
如果您计划在两台设备上使用 Box2D 来独立运行物理,那么您几乎肯定会在短时间内看到它们出现分歧。我在 iPad 2 和 iPad 3 上运行游戏,发现几秒钟后它们出现了分歧(其中一个发生了冲突,而另一个则没有)。这是因为浮点数的舍入行为因多种因素而异。对于一些快速计算来说,没有问题。但是,当这些值通过积分器不断循环时,小的差异会渗透到低阶位并累积(例如,正如您在物理模拟中看到的那样)。双精度有一点帮助,但最终没有帮助。
通过在多个 CPU 上的弹跳球场中查看特定弹跳球的一些简单测试(例如,对于完全相同的代码,iPad 2 与 iPad 3)将显示这一点。运动几秒钟后,错误就会逐渐出现,突然间,您的速度/位置就足以产生影响。
定点数学是解决这个问题的方法,但这种方法也会导致其自身的疯狂。曾经,Box2D 有一个定点版本,但这个时间已经过去了。
我什至尝试过制作一个定点版本的 Box2D,但被另一个项目(太空蜘蛛必须死!)分散了注意力。有一天...
对于您的特定情况(即您没有进行独立模拟或没有按照预期工作的方式进行模拟),这可能不是问题,如果不是,也不必担心。
您可以在我的博客上看到许多其他 Box2D 内容(但不是这个游戏......它还没有出现)。
这个有帮助吗?
| 归档时间: |
|
| 查看次数: |
2858 次 |
| 最近记录: |