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

发布于 2024-11-15 14:39:38 字数 292 浏览 4 评论 0原文

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

提前致谢。

So I'm writing a sort of particle simulator, like a "falling sand game" if you know what that is, and I've kind of hit a roadblock now. The way I'm doing this is I have a particle object that basically as of now has an position (int x, int y) and that's it. The way I'm drawing/moving them, is with a thread and the onDraw event for an android panel. Each time onDraw is called I loop through all the particles, move them down one pixel unless they hit the bottom and then draw them, this is pretty smooth until I get to about 200 particles, then the fps drops significantly. I know this is computation heavy the way I'm doing it, there's no debate about it, but is there any way I could do this to allow a lot more particles to be drawn and with less lag?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

往日情怀 2024-11-22 14:39:38

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

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

I take it you're using an individual-pixel drawing function for this? That would indeed be slow.

I see a couple ways to improve it. First is to put the pixels into an in-memory bitmap then draw the whole bitmap at the same time. Second, since particles are always just going down one pixel, you can scroll part of the bitmap instead of replotting everything. If Android doesn't have a scroll then just draw the bitmap one pixel down and start a new bitmap for the particles above the scroll. You'll have to fix up the particles on the bottom, but there are fewer of those.

小情绪 2024-11-22 14:39:38

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

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

  • 非移动粒子(静态粒子)(我将其称为 S 粒子)的加速度是它们不移动。将其标记为所有非移动区域(例如用户可能制作的不受重力影响的“墙”或“碗”)。如果粒子稳定,则将其上方的粒子标记为 S,例如对于液体,如果它具有 S对于像沙子这样堆积起来的东西,如果它下面的三个点都有一个 S,它就不会移动。一堆,你会得到很好的 45 度像这样的桩,我确信您可以更改它以使某些东西形成更陡峭或不太陡峭的桩。 Do S 映射下方
  • 没有粒子的粒子正在下落 - F 粒子。它们下面的F粒子也是F粒子,这些
  • 未标记的粒子F或S是复杂,它们可能开始下落,停止下落,或滚动,使用慢速处理器。已经有,对付他们, 最后,你所得到的应该

是很多很多快速的粒子,那些在一堆/湖里,还有那些像雨点一样落下。剩余的颗粒是那些位于斜坡边缘、湖泊顶部或其他复杂位置的颗粒。速度粒子的数量不应该那么多。

用某种颜色视觉标记每种颗粒,复杂颗粒为鲜红色。找到速度仍然很慢的情况,并查看您应该制作哪些其他类型的快速处理器。例如,您可能会发现制作大量沙堆会沿斜坡产生大量红色区域,您可能需要投资加速沿沙堆斜坡的“滚动区域”。

希望这是有道理的。一旦你弄清楚了一些事情,不要忘记回来编辑!

I've never done things like this before, but I have done some complex cellular automata. Sorry if this is too vague.

The basic idea here is to mark all particles that should "keep falling" or "not move" and exclude them from complex processing (with a special short/fast processor for the "falling" list - all you need to do is drop each one by a pixel).

  • The acceleration for non-moving particles - static particles (I'll call them S particles), is that they don't move. Mark it for all non-moving regions (like a gravity-immune "wall" or "bowl" that a user might make. Mark particles above it S if they are stable, so for example for liquid, if it has S particles under, and to both sides of itself, it will not move. For something like sand that forms piles, if it has an S in each of the three spots under it, it makes a pile, you'll get nice 45-degree piles like this, I'm sure you can change it to make some things form steeper, or less-steep piles. Do S mapping bottom-up.
  • The acceleration for particles with no particle under them is falling - F particles. Particles with an F particle under them are also F particles. Mark these bottom-up as well.
  • Particles unmarked F or S are complex, they may start falling, stop falling, or roll, use the slow processor, which you already have, to deal with them, there shouldn't be many.

In the end what you will have is many many fast particles. Those in a pile/lake and those raining down. The leftover particles are those on the edge of slopes, on the top of lakes, or in other complex positions. There shouldn't be nearly as many as there will be fast particles.

Visually mark each kind of particle with some colour, complex particles being bright red. Find cases where it is still slow, and see what other kinds of fast processors you should make. For example you may find that making lots of piles of sand creates lots of red areas along slopes, you may want to invest in speeding up "rolling zones" along the slopes of piles.

Hope it makes sense. Don't forget to come back and edit once you've figured something out!

素染倾城色 2024-11-22 14:39:38

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

编辑
另外,如果您仍然决定在 java 中进行处理,您应该查看 DDMS 中的方法分析。这将帮助您直观地了解性能瓶颈所在。

You may want to look into OpenGL ES hardware acceleration and renderscript. It doesn't give you a more efficient solution code wise (see the other answers for that). It does open up a lot more processing power for you to use however. You can even run the entire simulation on the GPU (possibly, don't know your implementation details).

Edit
Also, if you still decide to do the processing in java, you should look at Method Profiling in DDMS. This will help you visualize where your performance bottlenecks are.

无法言说的痛 2024-11-22 14:39:38

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

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

问候,
斯蒂芬

If you blur your image a bit, then you could just move half particule at a time, maybe one fourth only and print them all.. that would cut computation and the user wouldn't see it, getting the feeling all particules move.

But what ever you choose, I think you should be put a strong limit, not all users have powerfull android devices.

Regards,
stéphane

喵星人汪星人 2024-11-22 14:39:38

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

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

I think if particles are close each other, you can create objects that represent 3 or more particles.

When displaying several particles on screen, sets of grains maybe gets unnoticed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文