【问题标题】:How to make this more efficient?如何让这个更有效率?
【发布时间】:2012-04-01 01:35:39
【问题描述】:

我正在创建一个 Asteroids 克隆,但还有一些花里胡哨。

截至目前,我有一个 ArrayList<Asteroid>,它将所有小行星都显示在屏幕上。每个都有一个与之关联的Vector,并扩展了我的通用GameObject 类,该类处理绘制和更新以及每个游戏对象共有的其他常见事物。

也就是说,每次我摧毁一颗小行星时,我都会创建一个新的 Asteroid 对象并将其添加到 ArrayList<Asteroid>... 发生这种情况时会出现明显的延迟,因为我还会创建爆炸粒子,我假设这是GC。

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

这是正确的想法吗?还有什么是最有条理和最有效的方法?

任何其他想法也会很棒。只是试图减少所有这些对象的创建,因为它肯定会导致明显的滞后。谢谢!

【问题讨论】:

  • 您是否尝试过使用 DDMS 找出需要时间的地方?
  • 我的猜测是延迟是由于您的代码在创建新的小行星对象之前等待爆炸完成。尝试使爆炸的小行星动画异步?
  • @dan:我没有这样做,但我认为它会有所帮助。我不怎么用 DDMS,如何用它来查看耗时最长的部分?
  • @deed02392:我认为这不是问题,因为在每次渲染调用时,我都会检查是否检测到命中,如果是,我会为爆炸创建 50 个粒子,然后我只是更新它们位置以及其他一切......
  • 但是粒子的创建会阻塞后续帧渲染对吧?

标签: java android oop


【解决方案1】:

创建对象池并重用它们是个好主意。另外我认为你可以从ArrayList 切换到Vector,因为向量针对随机索引进行了优化,在使用池时你会做很多事情。

既然你说每次你摧毁一颗小行星,你就会添加一个新的,看起来你在处理恒定数量的小行星。因此,您可以创建具有恒定成员数量的池。

【讨论】:

  • 谢谢!我一定会切换到Vector。这是一个很好的建议,对未来的项目很有帮助。
【解决方案2】:

(1) 考虑使用享元模式设计您的对象。它是一种常用于具有重复特征的对象的模式。此处提供 java 代码示例:http://en.wikipedia.org/wiki/Flyweight_pattern

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

【讨论】:

  • 我想我肯定会转向预先创建我需要的对象。你是对的,因为我确实知道我需要创建的号码,那应该会有所帮助。我将研究享元模式。我喜欢它的声音。
【解决方案3】:

通常 Java 非常擅长分配新对象和执行最近创建的对象的 GC,因此我不会立即假设池化会大大改善事情。您确定您没有创建任何其他可能导致完全 GC(长时间暂停程序的 GC)的“垃圾”吗?

您可以通过启用“详细 GC 日志记录”来验证确实是 GC 导致了您观察到的问题(谷歌为此有几个 JVM 的命令行参数可以以不同的详细程度启用它)...

【讨论】:

  • 我不相信我正在创造其他“垃圾”,但我会仔细检查以确保。由于我在 Android 上,我不能使用标准 JVM,但我应该能够使用 DDMS 来确定 GC 的用途。
  • 我没有做过任何Android开发,所以我所说的可能不适用于Dalvik“JVM”。在开发实时嵌入式系统(我过去做过很多事情)时,池化是一种标准做法,并且将其发挥到极致(预先分配最常用的对象)在那些日子里为我解决了许多实时问题。然而,我怀疑很难让你的游戏“免费分配”,因为你使用的图形库很可能是动态分配的……
【解决方案4】:

我认为您的粒子效果是减速的罪魁祸首,而不是对象创建。

游戏开发人员通常会竭尽全力确保他们的图形速度很快,但在编写脚本时会做出许多性能折衷。这是有充分理由的:在大多数情况下,游戏对象的创建和存储对性能的影响与计算其物理特性和绘制图形的影响相比微不足道。

尝试减少粒子的数量和图形复杂性(特别是如果它们具有透明度;其效果很快就会叠加到疯狂)。

【讨论】:

  • 我认为你对粒子减速的看法是正确的。我将尝试在单独的线程中创建它们,看看是否有帮助。它们也确实具有透明度,因此这也是值得考虑的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多