0

私はAndroidゲームを開発しています。ゲームが進むにつれて、ゲームは着実に遅くなります。速度の変化の中には、敵の数が多いことなどによるものもあると思いますが、メモリリークが発生するのではないかと心配しています。

ゲームの性質は次のとおりです。

これは、リストと配列で構築されたタワーディフェンスゲームです。すべてのタワーデータは、多数のgameBoard配列に格納されています。描画および更新コード全体を通して、すべてのブロックが評価されます。ほとんどの場合、何もする必要はありません。ゲームは30x14グリッドであるため、ループの過程で420の場所がおそらく15回評価されます。これは素晴らしいプログラミングではありませんが、コードは十分に単純で、正常に機能すると思いました。そして、ほとんどの場合、何もする必要がないので、それが問題になるとは思いませんでした。

敵、すべての弾丸、およびさまざまなパーティクルエフェクトはすべて、以下のコードのようなリストに保存および更新されます。私は数日前にゲームのスキンを作成し、すべてのゲームロジックを同じに保ちながら、エフェクトを追加しました。ビットマップとカラーリングスタイルを追加しても、ゲームの実行方法は変わりませんでした。以下に示すようなパーティクルエフェクトを追加すると、速度の低下が明らかになりました。ゲームの早い段階で速度が低下することはありません。ゲームの後半で彼らはそうします。このため、メモリの管理が間違っていると思いました。

私はこのようなさまざまなクラスをたくさん持っています:

public class FadeBlock {
    private float x;
    private float y;
    private float radius;
    private int level;
    private float startRadius;
    private float endRadius;
    private float elapsedTime;
    private float fadeTime;
    private boolean terminate;
    private float percent;

    public FadeBlock(int Level, float CenterX, float CenterY, float StartRadius, float EndRadius, float FadeTime)
    {
        x = CenterX;
        y = CenterY;
        level = Level;
        fadeTime = FadeTime;
        terminate = false;
        percent = 1;
        startRadius = StartRadius;
        endRadius = EndRadius;
        radius = startRadius;
    }

    public void Update(float ElapsedTime)
    {
        elapsedTime += ElapsedTime;
        percent = (((float) elapsedTime) / ((float)fadeTime));
        radius = (endRadius - startRadius)*percent + startRadius;

        if (percent >= 1)
        {
            terminate = true;
        }
    }

    public void Draw(Canvas canvas, Paint paint)
    {
        if (!terminate)
        {
            switch (level) {
            case 1:
                paint.setARGB(255, 61, 190, 255);
                break;
            case 2:
                paint.setARGB(255, 162, 0, 194);
                break;
            case 3:
                paint.setARGB(255, 0, 194, 162);
                break;
            case 4:
                paint.setARGB(255, 129, 194, 0);
                break;
            case 5:
                paint.setARGB(255, 255, 85, 0);
                break;
            case 6:
                paint.setARGB(255, 194, 65, 0);
                break;
            default:
                paint.setARGB(255, 61, 190, 255);
                break;
            }
            paint.setAlpha((int) (255*(1 - percent)));

            canvas.drawRect(x-radius, y - radius, x + radius, y + radius, paint);
        }
    }

    public boolean Kill()
    {
        return terminate;
    }

}

次のようにarrayListに追加します。

public List<FadeBlock> FadingBlocks = new ArrayList<FadeBlock>();

そして、次のループで管理します。

for (int i = 0; i < FadingBlocks.size(); i++)
{
    FadingBlocks.get(i).Draw(canvas, paint);
}

for (int i = 0; i < FadingBlocks.size(); i++)
{
    FadingBlocks.get(i).Update(elapsedTime);
}

for (int i = (FadingBlocks.size() - 1); i > -1 ; i-- )
{   
    if (FadingBlocks.get(i).Kill())
{                       
        FadingBlocks.remove(i);
    }
}

リストにアイテムを追加するには、次のようにします。

FadeBlock tempBlock = new FadeBlock(Units.get(i).getLevel(), Units.get(i).getX()+16, Units.get(i).getY()+16, 16, 32, 250)                   
FadingBlocks.add(tempBlock);

それは私のオブジェクトを管理するための悪い方法ですか?それはAndroidデバイスで時間の経過とともにメモリの問題を引き起こしますか?

4

1 に答える 1

3

これまたはそれが数行のコードからメモリリークを引き起こすかどうかを知るのは本当に難しいです。ここにあなたのための考えがあります:

ゲームにObjectPoolパターンを使用します。ゲームの開始時にN個の敵を作成し、そのうちのいくつかは非アクティブです。次に、新しい敵が必要になったときに、新しい敵を作成してArrayListに追加する代わりに、非アクティブなプールから敵を取得してアクティブにします。同様に、敵を削除する代わりに、プールで非アクティブとしてマークするだけです。

ArrayListはxの容量で始まり、必要に応じて2xなどに増加するため、これによりメモリの過剰使用を防ぐことができますが、オブジェクトを削除してもメモリは解放されません。また、オブジェクトプールは配列リストではなく静的リストに格納します。これは、オブジェクトへの反復とアクセスが高速になるためです。

于 2012-07-05T15:16:21.837 に答える