0

我正在开发一款安卓游戏。随着游戏的进行,它会逐渐变慢。我确信一些速度变化是由于更高的敌人数量和类似的东西,但我也担心我可能有内存泄漏。

游戏的本质是这样的:

这是一款使用列表和数组构建的塔防游戏。所有的塔数据都存储在许多 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);

这是管理我的对象的坏方法吗?随着时间的推移,这会在安卓设备上导致内存问题吗?

4

1 回答 1

3

从几行代码中很难知道这个或那个是否会导致内存泄漏。这是给你的一个想法:

为您的游戏使用ObjectPool模式:您在开始游戏时创建 N 个敌人,其中一些是不活动的。然后,当您需要一个新敌人时,您无需创建一个新敌人并将其添加到您的 ArrayList 中,而是从不活动的池中取出一个并激活它。同样,您只需将其标记为在池中不活动,而不是删除敌人。

这可以防止内存过度使用,因为 ArrayList 以 x 的容量开始,并且在需要时会增加到 2x 等......但是当您删除对象时它永远不会释放内存。还将对象池存储在静态列表而不是数组列表中,因为迭代和访问对象会更快。

于 2012-07-05T15:16:21.837 回答