Libgdx游戏逻辑在Render中吗?

8

我正在学习Libgdx,并且对在渲染方法期间更新我的游戏逻辑有一些疑问。

我希望将我的游戏逻辑和渲染分开。原因是,如果我的系统上FPS很高,我的游戏循环会“运行”得更快。

我想要的是保持体验恒定并可能通过DeltaTime限制我的更新。如果有人可以指向如何进行以下教程: a)通过DeltaTime限制我的渲染更新 b)通过DeltaTime限制我的游戏逻辑更新。

谢谢:)


2
这是一篇优秀的文章:http://www.koonsolo.com/news/dewitters-gameloop/ - nullpotent
2个回答

8
重新阅读了您的问题后,我认为你错过了一个技巧(基于你的评论,即在更高刷新率的系统上运行会导致游戏逻辑运行得更快),那就是实际上你需要根据传递给渲染的“delta”时间来缩放更新。Andrei Bârsan在上面提到了这一点,但我想稍微详细说明一下如何使用delta。
例如,在我的游戏的render()中,我首先调用entityUpdate(delta),它通过以时间“delta”移动的距离来更新和移动我的游戏中所有对象的位置变量(不渲染它们,只移动它们的位置变量)。然后我调用entityManageCollisions(delta),解决由更新引起的所有碰撞,最后我调用entityDraw(batch, delta),使用delta获取精灵动画的正确帧,并实际将所有内容绘制在屏幕上。
我使用Entity/Component/System模型的变体,因此我通常以通用方式处理所有实体,而我上面提到的方法调用本质上是作用于具有特定组件组合的实体的“系统”。
所以,简而言之,将delta(传递到render()中的参数)传递到所有逻辑中,这样你就可以根据自上次调用以来经过的时间量来缩放物体(移动实体相应的距离)。这要求你为实体设置基于每秒单位的速度,因为你传递一个值来缩放它们,这是一秒的一小部分。一旦你做了几次,并尝试了结果,你就会掌握好的技巧。
另外请注意:这将在交互式调试会话中使你发疯,因为delta计时器会积累自上次渲染调用以来的时间,导致你的实体飞过整个屏幕(并超出边界-测试那些边界!)因为它们通常会获得子秒更新,但可能会被传递30秒(或者你花费的时间),所以在我的render()的最顶部,我有一行代码delta = 0.016036086f;(该数字是从我的开发工作站采样的delta,似乎给出了不错的结果-如果您喜欢,可以在测试运行期间将其写入控制台并使用该值代替)我在发布版本中注释掉,但在调试时留下未注释,这样每个帧都会将游戏向前移动相同的量,而不管我在调试器中花费的时间多长。
祝你好运!

1
不错的调试技巧(静态增量) - Revolutionair
在调试期间设置渲染循环中的增量是很聪明的做法,我不知道为什么我之前没有想到。 - dustinroepsch

3
到目前为止,答案并没有使用并行线程——我曾经有过这个问题,被建议不要这样做。链接。一个好的想法是先运行世界更新,如果帧中剩余的时间不足以进行渲染,则跳过渲染。仍然应该使用增量时间来保持一切顺利并防止延迟。
如果采用这种方法,明智的做法是防止连续发生超过X帧的跳帧,因为在(不太可能的情况下,但取决于更新逻辑与渲染相比有多少)更新逻辑持续时间超过分配给帧的总时间时,这可能意味着你的渲染从未发生——这不是你想要的事情。通过限制跳帧的帧数,您可以确保更新可以平稳运行,同时还可以保证游戏在处理过多逻辑时不会冻结。

你为什么认为使用并行线程不是正确的方法?render() 方法由图形模块调用,因此使用单独的线程会有好处。 - jellyfication
说实话,我只是假设libgdx主要用于Android游戏。而且目前还没有太多带有多核处理器的移动平台。 - Andrei Bârsan
没错 - 尽管有一些文章(尽管也很旧)建议在 render(...) 中完成所有操作,比如这篇文章:http://www.koonsolo.com/news/dewitters-gameloop/ - Andrei Bârsan
在哪里说不应该使用单独的线程? - jellyfication
让我们在聊天中继续这个讨论。点击此处进入聊天室 - jellyfication
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接