【问题标题】:XNA Particle System problemsXNA 粒子系统问题
【发布时间】:2013-06-10 14:55:31
【问题描述】:

我一直在 XNA 中制作粒子系统,我正在尝试创建两种粒子效果。烟花爆炸和喷泉烟花。

我遇到的问题是,当我向爆炸添加新粒子时(我这样做很快,因为我希望它们全部同时生成)帧速率大大下降。

我想知道是否有人可以解决这个问题。我看到官方示例使用了队列方法。这对我面临的问题有帮助吗?还是会使程序加载速度变慢,因为它必须在开始时将所有这些粒子加载到队列中?

添加新粒子:

        if (isActive)
        {
            timeSinceLastEmission += gameTime.ElapsedGameTime.Milliseconds;

            if (emitterFrequency == 0 || timeSinceLastEmission >= emitterFrequency)
            {
                emitterFrequency = emissionInterval;

                for (int i = 0; i < Math.Round(timeSinceLastEmission / emitterFrequency); i++)
                {
                    if (particleList.Count < MaxParticles)
                        addParticle();
                }

                timeSinceLastEmission = 0;
            }
        }

绘制函数:

    public void draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Begin();

        for (int i = 0; i < particleList.Count; i++)
        {
            spriteBatch.Draw(particleList[i].texture,
                             particleList[i].position,
                             null,
                             particleList[i].color,
                             particleList[i].rotation,
                             particleList[i].origin,
                             particleList[i].textureScale,
                             SpriteEffects.None,
                             0);
        }

        spriteBatch.End();
    }

任何帮助将不胜感激。

【问题讨论】:

  • 你的emitterFrequency和MaxParticles是多少?
  • 每种效果不同,但爆炸效果是 30 个粒子和 1.0f 频率,因此它们都同时生成。

标签: c# xna particle-system particles


【解决方案1】:

你需要做两件事:

首先,您需要将粒子类型设为 struct 而不是 class(我猜是这样。)

class 分配堆内存,您的列表将充满对位于堆上的那些对象的引用。这些堆对象中的每一个都需要由垃圾收集器管理。当您有很多对象时,这非常慢。 (对于太manyreasons这里详细介绍。)

然而,struct 将直接位于为列表分配的内存中。运行时可以执行诸如批量分配和清除内存之类的事情——速度要快得多。你的struct 比参考要大很多,所以尽量让它变小。你真的需要每个粒子的纹理和原点吗?你可以制作那些每个粒子系统。

(另一个很好的原因是SpriteBatch 如果避免纹理更改会更快,因为它们需要新的批次 - 很慢。)

其次,您应该将List.Capacity 设置为您的粒子系统的最大尺寸。

或者,更好的是,您可以使用列表的构造函数来设置起始容量。这将一次性分配您的列表所需的内存。每当列表达到容量时,它必须分配一个新的更大的列表,并复制其内容。所以,如果你一开始就足够大,它就不必重复做这个缓慢的操作了。


(注意:你会发现你不能在列表中的结构上设置单个成员,就像你可以对类一样——编译器会给你一个错误。你必须复制整个结构,修改它,然后将其复制回去。这还不错。但是,如果您愿意,可以通过使用数组来避免它 - 但是您必须自己管理大小和容量。)

(注意#2:此答案中的“慢”与优化粒子系统有关,因为您正在处理大量频繁更新的对象。这些操作在一般意义上并不慢。)

【讨论】:

  • 谢谢我会试试这个。我在一分钟内对所有粒子使用相同的纹理,直到它正常工作。
猜你喜欢
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2022-08-07
  • 2013-07-12
  • 1970-01-01
  • 2011-04-14
相关资源
最近更新 更多