【问题标题】:More Efficient Method of Drawing Thousands of Particles (Java/Android)绘制数千个粒子的更有效方法(Java/Android)
【发布时间】:2011-09-15 17:28:00
【问题描述】:

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

提前致谢。

【问题讨论】:

    标签: java android optimization draw particles


    【解决方案1】:

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

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

    【讨论】:

    • 这是android的drawPoint(x,y,Paint)函数。
    【解决方案2】:

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

    这里的基本思想是标记所有应该“继续下落”或“不动”的粒子,并排除它们进行复杂的处理(使用特殊的用于“下降”列表的短/快速处理器 - 您只需将每个像素下降一个像素)。

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

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

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

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

    【讨论】:

    • 这很有帮助,我可能会这样做
    【解决方案3】:

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

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

    【讨论】:

    • +1:真的,这里唯一合理的答案。 OpenGL 就是专门为进行这种处理而设计的。
    【解决方案4】:

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

    但是无论你选择什么,我认为你应该严格限制,并不是所有用户都有强大的安卓设备。

    问候, 斯蒂芬

    【讨论】:

      【解决方案5】:

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

      当在屏幕上显示多个粒子时,一组粒子可能会被忽视。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-31
        • 2012-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多