我最近了解到jMonkey只运行一个单独的线程,这是它的openGL渲染线程。但是我完全无法理解它。我可以理解它在单个更新循环上执行所有update和initialize()调用,但输入应独立于此更新循环,否则它将成为一个轮询机制。
答案 0 :(得分:4)
jME使用的方法在很多游戏引擎中非常常见(并且也用于其他一些用户界面库,如Swing)。
游戏引擎所做的一切都是在一个线程中完成的。这可以称为LWJGL线程,但由于jME可以使用LWJGL的替代品,因此将其称为Render Thread或jME Thread更为通用。
一切都确实在Render线程上完成,它确实使用了轮询机制。例如,如果您按住“左”键,则每个帧将在渲染线程上调用相关控件或应用程序状态,并将向左移动由tpf修改的量。 Tpf是每帧时间,对于保持平稳移动和让游戏系统以与帧速率无关的相同速度运行非常重要。
jME3中唯一通常使用单独线程的是物理引擎。它有一个用于进行物理更新的线程,然后使用适当的机制将更改推送到Render线程。系统会为您处理此问题,因此您无需担心这一点。
线程在游戏循环中运行。每次循环时,它都会检查它需要做的事情(如排队任务,初始化应用程序状态,渲染等等。它在每个活动的控制器和控件中调用更新等)。一旦完成更新所有内容,它就会继续执行渲染。所有这一切都发生在每一帧,但计算机是如此之快,它仍然可以处理所有这些并以良好的帧速率渲染游戏。
这是一个实施细节,您不必担心,除非知道它肯定会有效。实际上,添加实际排队并在下一帧中进行处理。
一切都是在同一个循环中处理的。 jME呼叫Nifty允许Nifty进行处理。作为处理过程的一部分,Nifty会检测事件并触发回调。这意味着回调已经在渲染线程中进入,因此您可以安全地修改场景图。 jME使用一些特殊编写的集合(如SafeArrayList)来允许您在迭代场景图的同时修改场景图。
更新,渲染,更新,渲染等。事件触发通常在检测到更新时作为更新过程的一部分发生。要通过查看Application类来查找代码,您应该能够通过start()
调用中的跟踪找到主游戏循环。
jME3线程教程涵盖了相当多的内容:
http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading