java - 池化 Box2d 实体?

标签 java libgdx box2d pooling

我正在尝试通过池化 box2d 主体来生成 block ,我不知道 libgdx 池化是否适用于主体,但如果是,请有人解释我如何做到这一点以及我的代码有什么问题。

首先,我在单独的方法上创建了 BodyDef 和 Body:

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
    }

然后为了生成 block ,我只需调用此方法:

public void spawnChunk(){
        createPlatform();
    }

我对此很陌生,我不知道 block 的含义是什么,但我知道它在横向滚动游戏中用于生成地形,我收到此错误消息:

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)

最佳答案

不要对 box2d 主体或关节使用池化,来自 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.

所以你只应该使用 Body body = world.createBody(bodyDef); 来创建主体。

接下来,将主体添加到某种列表中,这是绝对不应该做的!如果您需要访问世界上的所有实体,请按如下操作:

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

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

该错误意味着 Body 类没有类似的构造函数

public Body() {}

因此不能由通用池类实现创建,因为它尝试调用此构造函数。

要解决这个问题,您可以自己实现该池,但如上所述,您不应该这样做。

<小时/>

当前代码的另一个错误是您似乎误解了 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());

正如您在本示例中看到的,getFromPool(); 不起作用,因为您在下一行中为 pooledBody 分配了一个新值。

一个更简单的例子,说明为什么它不能按您的意愿工作:

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

总是打印 5,从不打印 4!

<小时/>

您可以池化的是 BodyDefFixutureDefShape 类,因为它们没有参数构造函数。

关于java - 池化 Box2d 实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33585281/

相关文章:

java - LibGDX 游戏崩溃并显示 "java platform se binary stopped working"

javascript - Box2dweb - 绳索接头不起作用

java - Box2d 中动态主体为空

java - 如何解决InputStream LeftoverDataException : Initialisation of record 0x85 left 18 bytes remaining still to be read

java - 带有 FTP 登录错误的 HTTPS 客户端 : javax.net.ssl.SSLException: 502 SSLv23/TLSv1 java

java - maven 是否有等效的 sbt-start-script?

java - 用于 XML 解析的 Android SimpleXML 库

android - IntelliJ IDEA 找不到android sdk

android - 重新读取 libgdx 中的内部文件

c++ - 使用 Objective-C 和 C++ 避免并行数组