0

我在一个游戏中工作,我每 1-3 秒生成一个对象。该游戏对象包含一些用于渲染目的的资产和一个 Box2D 主体。问题是我不想创建数千个对象。相反,我想重用它们,重置它的属性(位置、摩擦力等),而不是创建一个全新的对象。我认为最好的方法是实现这些对象的池,但我很担心,因为在搜索了一些信息后,我发现有几个开发人员报告内存泄漏,因为所有对象都是由 Box2D 在内部创建的。

您认为最好的方法是什么?

这是我用来表示每个游戏对象的类:

public class GameObject extends Box2dGameObject {

    private static final float WIDTH = 0.85f;
    private static final float HEIGHT = 1;

    private Animation animationDying;
    private Animation animationFalling;
    private Animation animationIdle;
    private Animation animationJumping;
    private Animation animationRunning;

    private Body body;

    public GameObject(Vector2 position, World world) {
        super(position, world);

        init();
    }

    private void init() {
        super.init();

        dimensions.set(WIDTH, HEIGHT);

        /* Get assets */
        animationDying = Assets.instance.pirate.animationDying;
        animationFalling = Assets.instance.pirate.animationFalling;
        animationIdle = Assets.instance.pirate.animationIdle;
        animationJumping = Assets.instance.pirate.animationJumping;
        animationRunning = Assets.instance.pirate.animationRunning;

        /* Set default animation */
        setAnimation(animationIdle);

        body = createBox2dBody();  
    }

    private Body createBox2dBody() {
        BodyDef bodyDef = new BodyDef();
        bodyDef.fixedRotation = true;
        bodyDef.position.set(position);
        bodyDef.type = BodyType.DynamicBody;

        PolygonShape shape = new PolygonShape();
        shape.setAsBox(WIDTH / 2, HEIGHT / 2);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.density = 1;
        fixtureDef.friction = 1;
        fixtureDef.shape = shape;

        Body body = world.createBody(bodyDef);
        fixture = body.createFixture(fixtureDef);

        shape.dispose();

        return body;
    }

    /* More code omitted */
}
4

1 回答 1

2

这似乎是一个早期优化的案例,可能不会产生您正在寻找的结果。

考虑:

  1. 所有位于“池”中的对象仍然在 Box2D 内部注册为对象。是否会对它们进行碰撞检查?会碰撞反应吗?他们的用户标签是否会指向“池”中的一个对象(用户标签通常用于引用主体的“所有者”)?
  2. 对象中的所有值都存在与生命周期相关的问题……您必须小心管理您放入和拉出的每个对象的值(位置很容易,但碰撞标志等变得更深)水池。这听起来容易出错。

如果您真的每秒只创建/销毁一个对象,那似乎对性能/内存的影响不大。如果你要创造数百个,那就是另一回事了。我写了一个游戏,我的子弹以每秒 10-20 的速度生成……每个都派生自一个复合的“实体”基类(我认为这个类称为“Slug”)。“Slug”类包含身体、精灵、碰撞处理逻辑等。当它发生碰撞或几秒钟后,它“死亡”并进入池中。从池中拉出它会导致它重新创建主体,我不认为这是性能或内存瓶颈。

它没有重新创建可能导致更大分配或不必要的部分(例如精灵)。这些在实际从池中删除之前不需要回收,因为它实际上只是对共享的精灵表的引用。一个特定的“Init(...)”方法与该类相关联,以便内存分配可以与初始化分开。

当然,您的里程可能会有所不同。但我认为你应该先看看它是否真的是一个问题(即原型它),然后再构建基础设施来修复它。

于 2014-03-27T10:15:19.103 回答