如何提高这个的效率?

6

我正在创建一个类似“陨石”的游戏,但是还有一些额外的功能。

目前,我有一个ArrayList<Asteroid>,用于保存屏幕上的所有陨石。每个陨石都与一个Vector相关联,并扩展了我的通用GameObject类,该类处理绘图、更新和其他每个游戏对象共有的常见事物。

话虽如此,每次我摧毁一个陨石时,我会创建一个新的Asteroid对象并将其添加到ArrayList<Asteroid>中……这时会出现明显的延迟,因为我还会创建爆炸粒子,我认为这是垃圾回收机制(GC)造成的。

我的想法是,不要动态地创建新对象,而是预先创建一个对象池,并重复使用它们。

这是否是正确的想法?另外,最有组织和高效的方法是什么?

如果有其他想法,也请告诉我。我只是想减少创建所有这些对象所造成的明显延迟。谢谢!


1
你尝试过使用DDMS查找耗时的原因吗? - 最白目
@deed02392: 我认为那不是问题,因为在每次渲染调用时,我都会检查是否检测到撞击,如果是,则创建50个粒子进行爆炸,然后我只需更新它们的位置以及其他所有内容... - Alex_Hyzer_Kenoyer
但是粒子的创建会阻塞后续帧的渲染,对吗? - deed02392
DDMS 中的分析方法:http://developer.android.com/guide/developing/debugging/ddms.html -(章节:“开始方法分析”)基本上,您可以开始记录应用程序并对其进行操作。完成后,您将在时间轴上获得有关调用方法的详细概述。 - 最白目
@dan:谢谢!我会这样做的,我真的应该早就知道哈哈。 - Alex_Hyzer_Kenoyer
显示剩余3条评论
4个回答

5
创建对象池并重复使用它们是一个好主意。此外,我认为您可以从ArrayList切换到Vector,因为向量针对随机索引进行了优化,而在使用池时,您将经常进行随机索引。
由于您说每次销毁一个小行星后,都会添加一个新的小行星,因此似乎您正在处理一定数量的小行星。因此,您可以创建具有恒定成员数的对象池。

谢谢!我一定会转换到Vector。这是一个很好的建议,对于未来的项目也很有用。 - Alex_Hyzer_Kenoyer

5

(1) 考虑使用享元模式设计对象。这是一种常用于具有重复特征的对象的模式。Java代码示例可在此处查看:http://en.wikipedia.org/wiki/Flyweight_pattern

(2) 如果您已经知道将使用多少个对象,则考虑将对象创建和其他初始化过程包含在加载页面中。


我认为我肯定要开始预先创建我需要的对象。你说得对,因为我知道需要创建的数量,这应该会有所帮助。我会研究一下享元模式。我喜欢它的声音。 - Alex_Hyzer_Kenoyer

4
通常情况下,Java在分配新对象和执行最近创建的对象的GC方面表现非常出色,因此我不会立即认为池化会大大改善事情。您确定没有创建任何其他可能导致完整GC(暂停程序一段时间的GC)的“垃圾”吗?
您可以通过启用“详细GC日志记录”来验证实际上是GC导致您观察到的问题(谷歌搜索这个,JVM有几个命令行参数可以以不同的详细级别启用它)...

我不相信我正在创建其他的“垃圾”,但我会好好检查一遍以确保。由于我在Android上,无法使用标准JVM,但我应该能够使用DDMS来确定GC正在做什么。 - Alex_Hyzer_Kenoyer
我没有做过任何Android开发,所以我说的话可能不适用于Dalvik“JVM”。在开发实时嵌入式系统(我过去做了很多)时,池化是一种标准做法,将其推向极致(预分配最常用的对象)解决了我在那些日子里遇到的许多实时问题。然而,我怀疑很难使你的游戏“无需分配内存”,因为你使用的图形库很可能会动态分配东西... - Javafanboy

4
我认为你的粒子效果是减速的罪魁祸首,而不是对象创建。
游戏开发者通常会尽力确保他们的图形快速运行,但在脚本编写方面做出了很多性能妥协。这是有很好的原因:在大多数情况下,创建和存储游戏对象的性能损耗与计算它们的物理和绘制其图形的性能损耗相比微不足道。
尝试减少粒子的数量和图形复杂度(特别是如果它们具有透明度;那么透明度的影响很快就会堆积到疯狂的程度)。

我认为你说得没错,粒子确实会导致减速。我打算尝试在单独的线程中创建它们,看看是否有所帮助。此外,它们还具有透明度,这也是需要考虑的事情。 - Alex_Hyzer_Kenoyer

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