我需要为我的游戏使用多线程吗?

3
我正在尝试使用OpenGL ES在Android上制作一个简单的打砖块游戏,但我无法决定是否需要为某些游戏逻辑(如更新游戏和碰撞检测)使用单独的线程。我已经创建了一个简单的原型:在它们自己的线程中并行绘制和更新。这带来了比我想象的更多问题,所以我想:

我需要多于一个线程吗?

例如,打砖块游戏有一个6X5个方块的网格,对于每个方块,它需要测试球是否触碰到该方块,而且每秒约30次。如果将此代码放入我的主要绘图循环OnDrawFrame(GL10)中,我担心它会花费大量渲染时间。
那么,我可以回到单线程游戏吗?(因为Android设备与PC相比不太强大)。
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
6
我正在尝试制作一个简单的打砖块游戏。 不,你不需要使用线程。 线程不适用于“简单”任务。线程适用于那些可能会出现性能问题的任务,这样你才能通过多线程获得实际收益。 通过为打砖块克隆版添加线程,你将会获得编码上的麻烦,仅此而已。它根本没有足够的重要性来需要线程,如果你不需要线程,几乎永远不应该使用它。

我不同意。多线程编程并不一定很难,而且在许多方面可以使游戏的逻辑更易于理解和处理。例如,将游戏的绘制放在一个线程中,将游戏的机制放在另一个线程中是非常合理的。这两个方面在代码中本来就应该分开处理。因此,为它们分配自己的线程不应该太困难。 - slayton
1
@slayton:然后你必须跨线程边界进行通信。这至少需要一种多线程队列,其中一个线程可以从中读取,另一个线程可以写入。这对于任何刚开始制作打砖块游戏的人来说都是无法正确处理的。即使对于专家来说,线程编程也很困难;对于新手来说,它是一个巨大的陷阱,会让他们调试数周甚至数月,却不知道为什么每千个游戏中就有一个会导致随机崩溃。 - Nicol Bolas
在简单的情况下,您真的不需要使用多线程队列,只需使您的方法“同步”,但是您是正确的,因为多线程要求您更多地考虑正在进行的操作,而不是在单线程应用程序中。然而,知道如何制作多线程应用程序是一项有价值的技能,并且并不难掌握。我的建议始终是告诉年轻的程序员他们不必使用它,但告诉他们为什么应该使用。 - slayton
我完全同意,多线程很容易导致随机/同步错误和崩溃,而且你的经验越丰富,就越好。一个非常大的问题是在问题中提到了 OnDrawFrame(GL10),当通过GLSurfaceView使用OpenGL|ES时,该代码已经在单独的线程上运行(即GLThread,该类创建)。 - MichalisB
值得一提的是,http://code.google.com/p/android-breakout/ 是一个使用GLSurfaceView的GLES 2打砖块游戏。它有两个“有趣”的线程,即主应用程序UI线程和渲染器线程。游戏几乎完全在渲染器中运行,这避免了大多数多线程问题,但仍需注意启动/关闭以及从应用程序UI线程接收触摸事件时的问题。 - fadden
我甚至在查找简单的数组值时都使用我的GPU,那么你如何同意单线程方法用于游戏?你如何使用单线程运行此示例?(http://www.codeproject.com/Articles/616115/Java-Thread-Example#lc)没有任何公式可用于确定是否使用线程! - user2511414

3

是的,你绝对不应该仅使用一个线程进行渲染和计算。

另外,您可能会发现关于实时Android游戏的IO讲座在这里很有用。


2
这是一个打砖块的克隆游戏。你真的认为这会有什么影响吗? - Nicol Bolas
从我评论中的视频,如果你跳到大约20:00,就会讨论这个问题以及为什么让所有计算都被硬件渲染阻塞通常不是一个好主意。对于这么简单的东西,你能在绘制循环中计算吗?也许可以。但线程并不是那么困难,值得一试。 - jqpubliq
我在一台486电脑上用解释型Pascal编写了一个Breakout克隆版,使用了极其低效的绘图例程。我认为Android设备可以处理它。此外,“硬件渲染”不会阻塞CPU;只有在交换缓冲区时,GPU才会阻塞CPU。即使这样,也要假设图形驱动程序本身没有线程化。 - Nicol Bolas

2

例如,一个打砖块游戏有一个6X5的方块网格,对于每个方块,它需要进行测试。

所以你每次更新时必须执行30个圆形-矩形测试。我认为当前的计算机足够快,可以每秒执行几十万次。

多线程使一些事情变得更容易,将渲染和游戏逻辑保持在不同的线程中是一种常见做法。但在你的情况下,带来的开销根本不值得。而且性能的提升只能在多核CPU上实现。


你不仅会在多核CPU上看到性能的提升,因为绘制被硬件渲染时间阻塞,这使得CPU大部分时间处于空闲状态。 - jqpubliq
@jqpubliq:这在很大程度上取决于您如何组织绘图函数。例如,如果您精确计时开始渲染到关闭glFinish,并知道屏幕刷新率,那么可以利用剩余时间(减去保护间隔)来做一些工作,然后再发出SwapBuffers。但是使用多线程不会增加总可用CPU时间。但是像我说的那样,使用多线程会使事情变得更容易。 - datenwolf

0

如果您的应用程序需要在多核系统上运行,那么多线程就有意义了。

当线程数超过核心数时,这被称为超额订阅,这通常是线程应用程序中的不良影响,因为它会增加额外的开销。

有时候,当您期望某些线程等待相当长的时间(例如文件系统上的读/写操作)时,超额订阅是有意义的。


1
使用多线程的原因不仅仅是并行处理,还有很多其他原因。毕竟,自单核处理器时代以来,它们就已经存在并被广泛使用了。 - MGZero
1
使用多个线程有很多原因,其中大部分与 CPU 核心数量无关。将应用程序进行多线程处理可以让您利用多个核心的优势。 - slayton
你怎么说呢?你的意思是单核赛扬处理器只能运行一个线程吗?你了解上下文切换吗? - user2511414

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