简体   繁体   中英

Pooling Box2d Bodies?

I'm trying to spawn chunks by pooling box2d Bodies, I don't know if libgdx pooling is applicable to bodies but if it is please someone explain me how to do it and what's wrong with my code.

first I created the BodyDef and Body on seperate methods:

public BodyDef createDef(){
        BodyDef def = new BodyDef();
        def.type = BodyDef.BodyType.StaticBody;
        def.fixedRotation = true;
        def.position.set(6, 6);

        return(def);
    }

    public Body createBody(){
        Body body = world.createBody(createDef());
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(1, 1);
        body.createFixture(shape, 1.0f);
        shape.dispose();

        return(body);
    }

 public void createPlatform(){
      Body platform = Pools.obtain(Body.class); //then use pooling
        platform = createBody(); //here I set the value equal to the return value of createBody() method 
        bodies.add(platform);//adding platform to the ArrayList
    }

then to spawn chunks I simply call this method:

public void spawnChunk(){
        createPlatform();
    }

I'm so new to this I don't know what's the meaning of chunk but I know that is used on side scrolling game for spawning terrain, I get this error message :

Exception in thread "LWJGL Application" java.lang.RuntimeException: Class cannot be created (missing no-arg constructor): com.badlogic.gdx.physics.box2d.Body
    at com.badlogic.gdx.utils.ReflectionPool.<init>(ReflectionPool.java:41)
    at com.badlogic.gdx.utils.Pools.get(Pools.java:29)
    at com.badlogic.gdx.utils.Pools.get(Pools.java:38)
    at com.badlogic.gdx.utils.Pools.obtain(Pools.java:48)
    at com.nivekbryan.ragingpotato.Physics.createPlatform(Physics.java:53)
    at com.nivekbryan.ragingpotato.Physics.spawnChunk(Physics.java:59)
    at com.nivekbryan.ragingpotato.WorldController.update(WorldController.java:17)
    at com.nivekbryan.ragingpotato.MainClass.render(MainClass.java:27)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)

Don't use pooling for box2d bodies or joints, from the box2d wiki:

So when you create a b2Body or a b2Joint, you need to call the factory functions on b2World. You should never try to allocate these types in another manner.

So you only should use Body body = world.createBody(bodyDef); to create bodies.

Next you add the bodies in some kind of list, which one should never do! If you need to access all bodies in your world, then do it like this:

// Global field
Array<Body> bodies = new Array<>();

// When you want to access the bodies.
world.getBodies(bodies);
for(Body body : bodies)
{
    // Do something
}

The error means that the Body class has no constructor that looks like

public Body() {}

And thus can not be created by the generic pool class implementation, since it tries to call this constructor.

To solve this you could implement the pool yourself, but as stated above, you should not do this.


Another error with your current code is that you seem to misunderstand variable assignment in java.

// gets a body from your pool, arbitrary method
Body pooledBody = getFromPool();

// assigns a new body to pooledBody, so your pooling is "voided".
pooledBody = world.createBody(createDef());

As you can see in this example the getFromPool(); has no effect, since you assign a new value to pooledBody in the next line.

A more simple example, on why it does not work as you wish:

int a = getFromPool(); // lets says this assigns 4 to a
a = 5;
System.out.println(a);

Will always print 5, never 4!


What you can pool is BodyDef , FixutureDef and the Shape classes, since these have no argument constructors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM