在LibGDX游戏中重用Box2D对象(池)

时间:2014-03-23 11:52:05

标签: java libgdx box2d object-pooling

我在一个游戏中工作,我每隔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 */
}

1 个答案:

答案 0 :(得分:2)

这似乎是早期优化的一种情况,可能无法产生您正在寻找的结果。

考虑:

  1. 所有坐在“池”中的对象仍然在Box2D内部注册为对象。是否会对它们进行碰撞检查?碰撞响应?他们的usertag是否会指向“池”中的对象(用户标签通常用于引用正文的“所有者”)?
  2. 存在与所有值相关的生命周期问题 对象...您必须小心管理每个被吸入和拉出池的对象的值(位置很容易,但碰撞标记等变得更深)。这听起来容易出错。
  3. 如果你真的只是每秒创建/销毁一个对象,那么这似乎不会影响性能/内存。如果你要创造数百个,那就是另一个故事。我写了一个游戏,我以每秒10-20的速度生成子弹......每个都来自一个“实体”基类,这是一个复合(我认为我称之为“Slug”类)。 “Slug”类拥有身体,精灵,碰撞处理逻辑等。当它碰撞或几秒钟后,它“死亡”并进入游泳池。从池中拉出它会导致它重新创建主体,我没有将其视为性能或内存瓶颈。

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

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