安卓游戏引擎设计:如何同步游戏循环和画布更新线程?

4
我想将我的简单游戏引擎重写为在Android上运行,并且我想知道如何同步两个正在运行的线程。现在我有以下内容:
Runner是主活动,也是该游戏的入口点;
CanvasView只是一个画布,用于绘制;
GameWorld是一个类,存储关于游戏状态的当前信息。现在,让我们假设它还包含一个Level。
GameLoop是一个单独的线程,用于更新游戏状态;
CanvasThread是一个单独的线程,用于在CanvasView上绘制当前Level。
由于级别只是一个简单的数组,因此CanvasThread只需遍历该数组并将其绘制在屏幕上。关于此,我有几个问题:
是否有可能按需运行CanvasThread的onDraw()方法?在引擎的当前状态下,它仅在执行前一个方法完成后才被重新启动。
我想实现一种GameLoop和CanvasThread之间的三向握手,类似于:
GameLoop -> CanvasThread:请停止更新
Canvas -> GameLoop:好的,已停止
GameLoop -> CanvasThread:好的,你可以恢复了。
最好的方法是什么?我是一个完全的Java / Android新手,所以我的引擎设置方式很可能不是最佳/最优的。如果您对设计有任何建议,我将非常感激。
谢谢。
PS:如果我在上面创建的图表中违反了所有最佳实践,请原谅我。
3个回答

2

我相信如果它们不进行通信,你会发现这样做更容易。

相反,加上一些限制以保持自己的理智:

  1. 制作一个非常紧密的游戏循环。如果你要更新画布,比如说,以30帧每秒(约33毫秒)的速度更新,那么让你的游戏循环不超过10或20毫秒。
  2. 在游戏循环和画布更新上设置锁。现在,每个操作都会等待另一个完成后再执行自己的任务。你不会出现画布在循环之前只显示了屏幕的一半,而在循环之后显示了另一半的情况。

例如:

class GameLoop extends Thread {

    public void run() {
        while(true) {
            synchronized(theGameWorldObject) {
                // update game info here
            }
        }
    }

}

class Canvas {
    updateCanvas() { // or whatever you call it
        synchronized(theGameWorldObject) {
            // update canvas here
        }
    }
}

2
Android有一种简单的方式来处理线程通信。您可以使用Looper和Handler在线程之间发送消息或完成Runnables。
请查看mindtherobot.com上的 Android Guts:Intro to Loopers and Handlers进行介绍。
您可以发送“空”消息以发出信号,或者提供一些参数。您可以立即发送消息,也可以延迟一段时间后再发送。
如果您通过向自身发送消息设计游戏循环,则很容易从其他线程注入消息。

2

1
这段代码将会提供非常大的帮助。我不想使用超级庞大的游戏引擎,我想要理解编写适当的安卓应用的内部知识。谢谢。 - zeroDivisible

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