0

XNA でパーティクル システムを作成しており、2 つのパーティクル エフェクトを作成しようとしています。花火の爆発と噴水の花火。

私が抱えている問題は、爆発に新しいパーティクルを追加すると(すべて同時にスポーンさせたいので、これを高速に行っているため)、フレームレートが大幅に低下することです。

これを改善するための解決策があるかどうか疑問に思っていました。公式の例では queue メソッドを使用していることがわかりました。これは私が直面している問題に役立ちますか? または、開始時にこれらすべてのパーティクルをキューにロードする必要があるため、プログラムのロードが遅くなりますか?

新しい粒子を追加:

        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();
    }

どんな助けでも大歓迎です。

4

1 に答える 1

1

次の 2 つのことを行う必要があります。

structまず、パーティクル タイプをではなく にする必要がありますclass(きっとそうだと思います。)

Aclassがヒープ メモリを割り当てると、リストはヒープ上にあるオブジェクトへの参照でいっぱいになります。これらの各ヒープ オブジェクトは、ガベージ コレクターによって管理される必要があります。多くのオブジェクトがある場合、これは非常に遅くなります。(理由が すぎて、ここで詳しく説明することはできません。)

ただし、 Astructは、リストに割り当てられたメモリに直接配置されます。ランタイムは、そのメモリを大量に割り当ててクリアするなどのことを行うことができます - かなり高速です。あなたstructは参照よりもかなり大きいので、できるだけ小さくするようにしてください. パーティクル単位のテクスチャとオリジンが本当に必要ですか? それらをパーティクルシステムごとに作成できます。

(別の正当な理由は、SpriteBatchテクスチャの変更を避けると、新しいバッチが必要になるため、速度が大幅に低下するためです。)

次に、List.Capacityパーティクル システムの最大サイズを設定する必要があります。

または、開始容量を設定できるリストにコンストラクターを使用することもできます。これにより、リストに必要なメモリ メモリが一度に割り当てられます。リストが容量に達するたびに、新しいより大きなリストを割り当て、その内容をコピーする必要があります。したがって、十分な大きさで開始すれば、この遅い操作を繰り返し行う必要はありません。


(注: クラスの場合のように、リスト内の構造体に個々のメンバーを設定することはできません。コンパイラーはエラーを返します。構造体全体をコピーして、変更し、元に戻す必要があります。これはそれほど悪くはありませんが、必要に応じて配列を使用して回避できますが、サイズと容量を自分で管理する必要があります。)

(注#2:この回答の「遅い」は、頻繁に更新される多数のオブジェクトを操作しているため、パーティクルシステムの最適化に関連しています。これらの操作は一般的な意味で遅くはありません。)

于 2013-06-10T16:43:23.127 に答える