java - 在 libgdx 中碰撞时出现主体的空错误(虽然不是)

标签 java libgdx box2d

P.s.这会很长,所以我建议你在阅读本文时喝早晨咖啡

这是错误

 java.lang.NullPointerException: Attempt to invoke virtual method 'com.badlogic.gdx.physics.box2d.Body developer.io.aimzballz.Blocks.getBody()' on a null object reference 
at void developer.io.aimzballz.Gameplay.beginContact(com.badlogic.gdx.physics.box2d.Contact) (Gameplay.java:336)
at void com.badlogic.gdx.physics.box2d.World.beginContact(long) (World.java:985)
at void com.badlogic.gdx.physics.box2d.World.jniStep(long, float, int, int) (World.java:-2)
at void com.badlogic.gdx.physics.box2d.World.step(float, int, int) (World.java:689)
at void developer.io.aimzballz.Gameplay.render(float) (Gameplay.java:231)
 at void com.badlogic.gdx.Game.render() (Game.java:46)
at void developer.io.aimzballz.Main.render() (Main.java:34)
at void com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(javax.microedition.khronos.opengles.GL10) (AndroidGraphics.java:459)
at void android.opengl.GLSurfaceView$GLThread.guardedRun() (GLSurfaceView.java:1531)
 at void android.opengl.GLSurfaceView$GLThread.run() (GLSurfaceView.java:1248)

这是出现错误的部分

@Override
public void beginContact(Contact contact) {
    for (int i = 0; i < l;i++){
        for (int x = 0; x < k;x++){
             if ((contact.getFixtureA().getBody() == ballz[i].getBody() &&
                    contact.getFixtureB().getBody() == blocks[x].getBody()) ||
                    (contact.getFixtureB().getBody() == ballz[i].getBody() && contact.getFixtureA().getBody() == blocks[x].getBody())) {
                blocks[x].decreaseScore();
                if (blocks[x].getScore() <= 0) {
                    handler.removeObject(blocks[x]);
                    final Body toRemove = blocks[x].getBody();
                    Gdx.app.postRunnable(new Runnable() {
                        @Override
                        public void run() {
                            world.destroyBody(toRemove);
                        }
                    });
                }
            }
        }
    }
}

奇怪的是......这个错误有时会出现,有时不会,不仅如此,我还通过Timer安排了一个任务,它有时会执行任务,有时不会。
是时候清理一些东西了,ballz[]blocks[] 是游戏对象(扩展名为 GameObject 的抽象类的类),如果您无法理解我的代码的含义,我可以解释,但现在我想向您展示另一件事

private void translateBlocks(){
    for (int i = 0; i < k;i++){
        blocks[i].getBody().setLinearVelocity(0, 3);
    }
    Timer.schedule(new Timer.Task() {
        @Override
        public void run() {
            stopBlocks();
        }
    } , 0.75f);
}
private void stopBlocks(){
    for (int i = 0; i < k;i++){
        blocks[i].getBody().setLinearVelocity(0,0);
        created = false;
    }
    k = k + rnd.nextInt(2) + 1;
    diffOfK = k - diffOfK;
    createBlocks(k , diffOfK);
}

k是现有 block 的数量,createBlocks正如其听起来的那样
ballz 中的对象在创建 block 后发生碰撞时,我得到了在开始时显示的空错误
这就是我希望解决我的问题的一切...如果我错过了任何事情或者如果您对我的代码有任何疑问,请随时发表评论
编辑
处理程序类

public class Handler {

LinkedList<GameObject> object = new LinkedList<GameObject>();

public void render(ShapeRenderer renderer){
    for (GameObject tempObject : object) {
        tempObject.render(renderer);
    }
}
public void dispose(){
    for (GameObject gameObject : object){
        gameObject.dispose();
    }
}
public void textRender(SpriteBatch batch){
    for (GameObject gameObject : object){
        gameObject.textRender(batch);
    }
}

public void addObject(GameObject object){
    this.object.add(object);
}
public void removeObject(GameObject object){
    this.object.remove(object);
}

} 这是 video显示发生了什么

好吧,我想澄清一些事情,我的问题不是删除物体或物体,在创建新 block 后以及当任何 ballz 与任何物体碰撞(即使它不是 block )时,我会收到错误,请观看视频以了解我在说什么,顺便说一句,分数代表 block 上的数字您可以在视频中看到

最佳答案

首先,您应该确保灯具不为空。我几乎 100% 确定您在迭代时遇到 null block 。

我会提出这样的解决方案:

    public void beginContact(Contact contact) 
    {
        Fixture fixA = contact.getFixtureA();
        Fixture fixB = contact.getFixtureB();

        if(fixA == null || fixB == null) return;

        if(fixA.getUserData() instanceof Ball || fixB.getUserData() instanceof Ball)
        {
            Fixture ballFixture = fixA.getUserData() instanceof Ball ? fixA : fixB;
            Fixture blockFixture = fixA.getUserData() instanceof Ball ? fixB : fixA;

            Block block = ((Block)blockFixture.getUserData());

            block.decreaseScore();
            //and all other functions
        }

    }

我假设 ballz 和 block 数组中的元素属于不同类型,如果不是,则将它们设为不同类型。 当然,为了使我的代码正常工作,您必须在创建灯具时设置灯具的用户数据。

body.createFixture(fixtureDef).setUserData(ball);

block 相同。

您还应该考虑使用一些列表而不是数组。

关于java - 在 libgdx 中碰撞时出现主体的空错误(虽然不是),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45918039/

相关文章:

java - Swing 问题!(显示框架的问题)

java - LibGDX渲染和更新调用速度

java - 圆圈扇区内 child 的最大尺寸

java - 折线轮廓构造/绘制粗折线

javascript - 一帧内移动的线速度和距离

python - 属性错误 : module '_Box2D' has no attribute 'RAND_LIMIT_swigconstant'

java - 快速切换位顺序的方法?

java - 通过配置更改保留对象的静态模式

java - Box2d - 加速和限制轮子的速度

java - 使用 Java 字符串格式生成不带前导零的可变大小数字