模拟虚拟世界:连续或离散的步骤?

我正在做一些类似于Polyworld的东西,这意味着我将模拟虚拟世界,在那里爬虫小跑,吃东西和进化。 我是用Node.js做的,我打算使用物理和neural network,但是我不确定更新世界的最佳方式是什么,更具体地说,如果更新函数将delta时间作为参数,或者每次做同样的事情,独立于最后一次被叫的时间? 两种方式有什么好处?

编辑:我反对不断更新的一点是,我想要实现某种间隔,例如,每20个模拟秒食物块产卵。 如果dt变得不同于1(或者1的一小部分),那么这将永远不会精确地工作。

再次,如果我去离散更新,更新不关心多less时间过去了,我将无法“减慢时间”。 当我在一个function强大的服务器上工作并在浏览器中进行渲染时,我认为更新会经常发生,而且我需要一种减慢时间的方法,而不会影响仿真,所以我可以看到发生了什么。

如果你没有多个代理(每个都有自己的线程)必须协作,你不必处理stream程问题的同步/事件,我build议你使用连续模拟。 使用固定的时间步骤,并在每一步中改变你的世界的状态。 每个世界的一块改变它的状态使用一个function如:

newState = f(oldState,deltaSteps)

关于你提到的速度问题,不要直接将你的迭代映射到时间。 定义一个中间时间单位(步),他们将这个单位时间映射到毫秒,迭代或你喜欢的。 所以如果你想增加或者减less你的模拟速度,只需要改变用于逐步转换的因子。 如果你需要改变速度,只需改变你的常数。

查看本页面 ,了解有关模拟技术的一些信息。

每次调用更新函数时,都可以计算自animation开始以来经过的时间。 然后你把这个时间传递给更新函数,即使帧不可能在20秒精确更新,你也可以根据实际的时间进行所有的计算。

例如:汽车在20秒开始运动,速度为3单位/秒。 假设更新函数在以下时间被触发:…,19.35s,20.67s,…在19.35s更新时,你知道它还不应该被移动,所以什么都不会发生,但是当更新函数被触发时间值20.67s那么你知道车已经跑了0.67s,所以你计算它的位置(时间*速度)0.67 * 3 = 2.01,并且做所有其他的计算/绘制,就好像它已经移动了2.01个单位。 这样你就不用担心精确的时间测量,滞后,更新function比平时花费更多的时间等等。

我想你不要超过一定的频率(如50赫兹)。 这会浪费CPU时间在不必要的精度。

如果用户的设备无法提供更新率,那么您也是

  1. 保持相同的物理频率,并降低壁钟速度
  2. 用更高的ΔT降低物理频率

如果频率仍然高于20Hz,我会select2。 如果它下降,你可能应该切换到策略1,以保持精度。

所以你可能需要一个基于deltaT的解决scheme,所以你可以调整更新频率。

您的更新function应该在每一步执行相同的操作。

这两种方法都有缺陷,但是当模拟群体中的多对多交互时,传递代表自上次更新之后所经过的时间的增量变得难以pipe理。 这是因为预测交互发生的时间点(增量)是非常耗时的。 如果错过了这些时间点,则模拟不准确。

在每个时间步骤更新所有元素的方法的缺点是它会做不必要的工作。 然而,这种不必要的工作的成本可能会低于准确预测需要评估哪个时间点的工作量,尤其是考虑到复杂的交互环境。

我想你会希望你的animation是连续的,并且基于一些经过的时间或时钟(你可能会加快或减速)。 所以一些更新函数,你会想要基于增量。

但这并不意味着你不能使用setInterval来产生食物块。 这也并不意味着其他一切都需要或应该以三angular洲为基础。

例如,您可以在位置更新之后检查彼此靠近的生物或生殖所需的任何条件,然后生成后代作为不依赖于当前时钟的离散步骤。 你会想logging什么时候发生的事情。

我会用恒定的时间步。 编码要容易得多。 每个更新function根据环境做一步。 您不必每一步都更新浏览器。 您可以计算10或100个步骤,然后将结果发送到浏览器。

这样做会更准确。 很多小的简单步骤比delta时间函数(恶梦)更容易编码。

如果你正在使用可变的时间步骤。 当时间步长很大的时候,你可能会出现这样一种情况,一只ant在t0的点A和t + delta的B点。 你首先更新ant,它在B点结束。你更新A和B之间的食物重生点,应该在t0 + 1/3三angular洲重生。 ant没有看到食物就经过。 模拟是错误的。

其他你可能需要的东西:

  • 要真正准确,你必须检查段之间的碰撞[先前的位置 – 新的位置],而不是点。 否则,ant可能会交叉而不会碰撞。 检查物理引擎。
  • 避免将所有对象发送到您的浏览器。 使用八叉树或四叉树可以快速确定与浏览器显示的区域相对应的数据。

在Node.js中做这件事的奇怪的select,我会使用Java或一个真正的oop语言。

你会在游戏开发者论坛上find很多有用的帮助。