6

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

提前致谢。

4

5 回答 5

2

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

编辑
另外,如果您仍然决定在 java 中进行处理,您应该查看Method Profiling in DDMS。这将帮助您可视化您的性能瓶颈在哪里。

于 2011-06-15T17:30:24.510 回答
2

我认为您为此使用了单个像素绘图功能?那确实会很慢。

我看到了一些改进它的方法。首先是将像素放入内存位图中,然后同时绘制整个位图。其次,由于粒子总是只下降一个像素,您可以滚动位图的一部分而不是重新绘制所有内容。如果 Android 没有滚动条,那么只需将位图向下绘制一个像素,然后为滚动条上方的粒子创建一个新的位图。您必须修复底部的颗粒,但数量较少。

于 2011-06-15T17:21:44.630 回答
2

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

这里的基本思想是标记所有应该“继续下落”或“不移动”的粒子并将它们排除在复杂的处理之外(为“下落”列表使用特殊的短/快速处理器 - 您需要做的就是放下每个一个像素)。

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

最后你会得到很多很多的快速粒子。那些在一堆/湖里的和那些下雨的。剩余的颗粒是那些在斜坡边缘、湖泊顶部或其他复杂位置的颗粒。应该不会有快粒子那么多。

用某种颜色直观地标记每种颗粒,复杂的颗粒呈鲜红色。找出它仍然很慢的情况,看看你应该制造哪些其他类型的快速处理器。例如,您可能会发现制作大量沙堆会沿斜坡产生大量红色区域,您可能希望投资加速沿沙堆斜坡的“滚动区”。

希望这是有道理的。一旦你弄清楚了,别忘了回来编辑!

于 2011-06-15T17:53:46.927 回答
0

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

在屏幕上显示多个粒子时,可能不会注意到一组粒子。

于 2011-06-15T17:22:52.000 回答
0

如果你稍微模糊你的图像,那么你可以一次只移动半个粒子,也许只移动四分之一并将它们全部打印出来......这会减少计算并且用户不会看到它,感觉所有粒子都在移动。

但是无论您选择什么,我认为您应该受到严格的限制,并非所有用户都拥有强大的 android 设备。

问候, 斯蒂芬

于 2011-06-15T17:08:56.527 回答