为什么在 Libgdx Bullet 中派生的 class 的 ContactListener 中的数组大小始终为零?

Why Array size in my ContactListener derived class in Libgdx Bullet is always zero?

我正在尝试在 Libgdx 中创建一个 ContactListener 派生的 class 使用 Bullet wrapper 进行碰撞检测,就像在这个 tutorial 中一样,但在单独的 class 中es。它将渲染和游戏世界分开 classes。在 class Renderrender() 方法中,我将一个模型实例数组传递给这个派生的 class。但是当我 运行 它给出了一个因为数组大小为零。这是派生的 class :

package com.anutrix.brickbreaker3d.Helpers;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.physics.bullet.collision.ContactListener;
import com.badlogic.gdx.utils.Array;

public class CollisionListener extends ContactListener {

    private Array<ModelInstance> instances;

    public CollisionListener() {
        this.instances = new Array<ModelInstance>();
    }

    public void setModelInstances(Array<ModelInstance> instances) {
        this.instances = instances;
    }

    @Override
    public boolean onContactAdded(int userValue0, int partId0, int index0, int userValue1, int partId1, int index1) {
//instances.get(colObj1Wrap.getCollisionObject().getUserValue()).collided = false;error
        Gdx.app.log("instances.size", Integer.toString(instances.size));//zero
        Gdx.app.log("ddhbdfhd", "fhfgjfgj");
        return true;
    }
}

这是渲染器 class:

package com.anutrix.brickbreaker3d.gameWorld;

import com.anutrix.brickbreaker3d.gameObjects.Ball;
import com.anutrix.brickbreaker3d.gameObjects.Brick;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.physics.bullet.DebugDrawer;
import com.badlogic.gdx.physics.bullet.collision.btCollisionDispatcher;
import com.badlogic.gdx.physics.bullet.collision.btCollisionWorld;
import com.badlogic.gdx.physics.bullet.collision.btDbvtBroadphase;
import com.badlogic.gdx.physics.bullet.collision.btDefaultCollisionConfiguration;
import com.badlogic.gdx.physics.bullet.linearmath.btIDebugDraw;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable;

public class GameRenderer implements Disposable {

    private GameWorld gameWorld;
    private PerspectiveCamera cam;
    public ModelBatch modelBatch;
    private CameraInputController camController;
    private Environment environment;
    public Array<ModelInstance> instances;
    ModelBuilder mb = new ModelBuilder();
    btCollisionDispatcher dispatcher;

    public GameRenderer(GameWorld world) {
        this.modelBatch = new ModelBatch();
        this.environment = new Environment();
        this.instances = new Array<ModelInstance>();

        gameWorld = world;
        cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        cam.position.set(10f, 10f, 0f);
        cam.lookAt(0, 0, 0);
        cam.near = 1f;
        cam.far = 300f;
        cam.update();

        camController = new CameraInputController(cam);
        Gdx.input.setInputProcessor(camController);
        environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
        environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));


    }

    public void render() {
        //Gdx.app.log("GameRenderer", "render");
        Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        Gdx.gl.glClearColor(0f, 0.2f, 0.2f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

        for (Brick b : gameWorld.bricks) {
            b.getObject().setUserValue(instances.size);
            instances.add(b.getModelInstance());
        }
        for (Ball b : gameWorld.balls) {
            b.getObject().setUserValue(instances.size);
            instances.add(b.getModelInstance());
        }

        gameWorld.collisionListener.setModelInstances(instances);

        modelBatch.begin(cam);
        modelBatch.render(instances, environment);
        modelBatch.end();

        instances.clear();

    }

    @Override
    public void dispose() {
        modelBatch.dispose();
    }

}

我做错了什么? setModelInstances() 里面的 instances.size 是正确的。但是在每次调用它之后, instances.size 等于 0 。 我也不确定引用传递(因为 Java 使用值传递)。那么,如果我只调用一次 setInstances() 是否更好(如果有效)?

GameRenderer#render() 方法中调用 gameWorld.collisionListener.setModelInstances(instances); 后,CollisionListener#instancesGameRenderer#instances 都指向同一个引用。

然后,在该方法的末尾,您将调用:

    instances.clear();

这将清除 instances。因此,当您调用 render.

时,大小将变为 0

相反,在您的 setModelInstances 方法中,您可以像这样创建一个新的 Array 实例:

public void setModelInstances(Array<ModelInstance> instances) {
    this.instances = new Array<>(instances);
}

希望对您有所帮助!