绘制数以千计的粒子的更有效方法(Java / Android)

时间:2011-06-15 17:00:41

标签: java android optimization draw particles

所以我正在编写一种粒子模拟器,如果你知道那是什么,就像一场“落砂游戏”,我现在已经遇到了障碍。我这样做的方式是我有一个粒子对象,基本上现在有一个位置(int x,int y),就是这样。我正在绘制/移动它们的方式是使用线程和Android面板的onDraw事件。每次调用onDraw时,我都会遍历所有粒子,将它们向下移动一个像素,除非它们击中底部然后绘制它们,这是非常平滑的,直到我得到大约200个粒子,然后fps显着下降。我知道这是计算方式,我正在做的事情很重要,没有关于它的争论,但有没有办法我可以做到这一点,以允许更多的粒子被绘制和更少的滞后?

提前致谢。

5 个答案:

答案 0 :(得分:2)

我认为你正在使用单个像素绘图功能吗?那确实会很慢。

我看到了几种改进方法。首先是将像素放入内存中的位图,然后同时绘制整个位图。其次,由于粒子总是只向下移动一个像素,因此您可以滚动部分位图而不是重新绘制所有内容。如果Android没有滚动,则只需将位图向下绘制一个像素,然后为滚动上方的粒子开始新的位图。你必须修复底部的颗粒,但这些颗粒更少。

答案 1 :(得分:2)

您可能希望查看OpenGL ES硬件加速和renderscript。它没有为您提供更有效的解决方案代码(请参阅其他答案)。它确实为您提供了更多的处理能力。您甚至可以在GPU上运行整个模拟(可能,不知道您的实现细节)。

修改
此外,如果您仍然决定在java中进行处理,则应该查看Method Profiling in DDMS。这有助于您了解性能瓶颈的位置。

答案 2 :(得分:2)

我以前从未做过这样的事情,但我做了一些复杂的细胞自动机。对不起,如果这太模糊了。

这里的基本想法是标记所有应该“保持下降”或“不移动”并且排除它们的复杂处理的粒子(使用特殊的用于“下降”列表的短/快处理器 - 您需要做的只是将每个像素丢弃一个像素。)

  • 非移动粒子的加速度 - 静态粒子(我称之为S粒子),就是它们不会移动。将它标记为所有非移动区域(如用户可能制造的重力免疫“墙”或“碗”。如果它们是稳定的,则标记其上方的粒子,例如对于液体,如果它具有S,则为在它自身的下方和两侧,它不会移动。对于形成桩的沙子,如果它下面的三个点中的每一个都有一个S ,它会使一堆,你会得到像这样漂亮的45度桩,我相信你可以改变它,使一些东西形成更陡峭或更陡峭的桩。自下而上的映射。
  • 没有颗粒的颗粒的加速度正在下降 - F颗粒。其下具有F颗粒的颗粒也是F颗粒。自下而上标记这些。
  • 没有标记的粒子F或S 复杂,它们可能会开始下降,停止下降或滚动,使用你已经拥有的慢速处理器来处理它们,应该没有很多

最终你将拥有许多快速粒子。那些在一堆/湖中和那些下雨的人。剩下的颗粒是位于斜坡边缘,湖泊顶部或其他复杂位置的颗粒。不应该有快速粒子的数量。

视觉上标记各种颜色的粒子,复杂的粒子是鲜红色。查找速度仍然很慢的情况,并查看您应该制作的其他类型的快速处理器。例如,您可能会发现制造大量沙子会在斜坡上形成大量红色区域,您可能希望投资加速沿着斜坡堆积的“滚动区域”。

希望它有意义。一旦你想出了什么,别忘了回来编辑!

答案 3 :(得分:0)

如果你模糊了一点图像,那么你可以一次只移动半个粒子,也许只有四分之一并打印它们......这会削减计算量而且用户不会看到它,感觉所有粒子移动。

但无论你选择什么,我认为你应该受到强烈限制,并非所有用户都拥有强大的Android设备。

此致  斯特凡

答案 4 :(得分:0)

我认为如果粒子彼此靠近,你可以创建代表3个或更多粒子的对象。

当在屏幕上显示几个粒子时,可能会忽略一组粒子。