我想使用 opengl es 在 android 中编写一些简单的游戏,但立即遇到了主游戏循环的问题。正如我在这里读到的:http://developer.android.com/resources/tutorials/opengl/opengl-es10.html每次需要重绘表面时,应用程序都会调用 public void onDrawFrame(GL10 gl)
。或者那样的事。我的问题是 - 如何创建独立于绘制调用的更新循环。我的意思是 - 它不能那样工作,我无法仅在设备(应用程序?)想要重绘表面时更新游戏逻辑(或者我错了吗?)。
经过一番谷歌搜索后,我得出结论,我必须为更新循环创建另一个线程。但后来我遇到了另一个问题——一个线程负责绘图,另一个线程负责更新游戏逻辑,我不知道如何让它们合作。首先,它们是两个独立的类(至少在我的实现中是这样),所以它们不能使用相同的游戏变量和对象( Sprite 、计时器、不同的变量、计数器等等……几乎这两个类需要做的所有事情他们的工作)。现在我想我可以以某种方式将它们都打包到一个类中。但是 - 其次,我需要以某种方式同步这两个线程。
最后,我得出了这样一个大概的想法:
- 3 类:
公共(public)类 MyRenderer 实现 GLSurfaceView.Renderer
并使用onSurfaceCreated()
方法处理绘图公共(public)类 UpdateThread 使用
。run()
和update()
方法实现 Runnablerun()
每秒准确调用update()
方法 60 次(我想要一个固定步长循环)public class SpritesHolder
用作所有游戏对象/变量/内容(如 Sprite 、计时器、状态变量等...)的容器,所有字段都是公开的。
- 所以基本上
SpritesHolder
类是一个盒子,在一个地方包含所有需要的变量,所以MyRenderer
和UpdateThread
类可以访问它并且使用它。 至于同步 - 我只是这样做了:
public void update(float delta) { synchronized (spritesHolder) { // whole method code... } }
和:
public void onDrawFrame(GL10 gl) { synchronized (spritesHolder) { // whole method code... } }
这样两个线程就不会同时使用 spritesHolder。因此更新每秒完成 60 次,只要应用(设备?)需要,就会进行绘图。
说了一大堆,不好意思,这篇文章快写完了。 ;) 所以无论如何 - 这(如上所述)有效,我什至确实根据这个"template"编写了一些游戏,但我认为我的想法可能很疯狂,并且可以更好地设计它。我将非常感谢所有评论和建议。
最佳答案
您的解决方案可能会奏效,但它可能无法达到最佳性能。如果您考虑一下,渲染线程和更新线程实际上并不需要 100% 独占。
我最近花了一段时间为我的游戏考虑这个问题,这就是我最终想到的(不一定更好,但只是一些值得思考的东西):
对于每个可渲染对象,我有一个对象由更新线程拥有,另一个对象由渲染线程拥有,它只是一个普通容器,其中包含有关如何绘制对象的说明(模型矩阵、统一值、meshID、 ETC)。我运行更新线程计算我的可渲染对象的所有最终位置和值,然后我同步一个小窗口,我将在该帧期间更改的任何值传递给可渲染线程中的对象。然后,一旦新信息通过,就开始渲染帧,同时运行下一个更新帧。因为只有一个小的排除窗口,它允许更新和绘制线程在大多数时间同时运行。
关于android - 如何使用 android opengl 适本地创建更新/绘制循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9914977/