【问题标题】:Why Array size in my ContactListener derived class in Libgdx Bullet is always zero?为什么 Libgdx Bullet 中我的 ContactListener 派生类中的数组大小始终为零?
【发布时间】:2017-03-08 09:43:47
【问题描述】:

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

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;
    }
}

这里是渲染器类:

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() 会更好(如果可行的话)吗?

【问题讨论】:

    标签: java arrays libgdx bulletphysics


    【解决方案1】:

    在您的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);
    }
    

    希望这会有所帮助!

    【讨论】:

    • 那我该如何替换 instances.clear(); 。如果我删除它,每个循环之后的实例数只会增加。
    • @Anutrix 您可以将数组复制到setModelInstances(而不是分配引用)
    • 我认为分配引用会占用更少的空间。另外“如果”它会起作用,我只能打电话给setInstance()一次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 2011-02-07
    • 2016-02-07
    • 2011-01-22
    • 1970-01-01
    • 2015-07-28
    相关资源
    最近更新 更多