繁体   English   中英

删除body box2d

[英]Delete body box2d

谁能告诉我为什么这会返回错误

'AL lib:(EE)alc_cleanup:1个设备未关闭'

// mouseJoint碰撞回调

private QueryCallback queryCallback = new QueryCallback() {

    @Override
    public boolean reportFixture(Fixture fixture) {


        if(fixture.getBody() == chest){

            //add to remove list

            bodiesToRemove.add(chest);

        }

        if (fixture.testPoint(tmp.x, tmp.y)){


            reportFixture = fixture.getBody();
        }


        if (!fixture.testPoint(tmp.x, tmp.y))
            return false;

        //assigning bodyB to fixture 
        jointDef.bodyB = fixture.getBody();
        jointDef.target.set(fixture.getBody().getWorldCenter());

        //jointDef.target.set(tmp.x, tmp.y);// initial target point coincide with body anchor

        joint = (MouseJoint) world.createJoint(jointDef);// creating the join the physics world
        return false;
    }

};

//主渲染循环

public void render(float delta) {
    // TODO Auto-generated method stub
       //code clears the screen with the given RGB colour (black)
    Gdx.gl.glClearColor( 0f, 0f, 0f, 1f );
    Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );


     stage.setCamera(camera);               
     stage.act(Gdx.graphics.getDeltaTime());




    camera.position.x= chest.getPosition().x;


    camera.update();

     stage.draw();



    world.step(1 / 60f, 8, 3);
    renderer.render(world, camera.combined);


/////////////////////////////////////////////////////////////////   

//这是我尝试删除正文时导致错误的代码

    if(bodiesToRemove != null){

    for(int i = 0; i <bodiesToRemove.size; i++){

        Body b = bodiesToRemove.get(i);

        if(b != null){
           world.destroyBody(b);
           b.setUserData(null);
           b = null;
        }
        bodiesToRemove.clear();
    }
    }

    ////////////////////////////////////////////////////////////
}

///////////////////////////////////////////////////// /////////////////////////如果有人想解释正确的方法,我已经更改了它的工作原理(粘贴在下面)这或如果这是有用的正确方法。 我只是添加了一个布尔值以防止其破坏关节

// ////////////////// TOUCH EVENT ///////////////////////////////
//Called when a finger was lifted or a mouse button was released.
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    //If no mouseJoint do nothing

    System.out.println("touch" + (screenY*0.01f));
    System.out.println("touch" + (screenX*0.01f));



    if (joint == null)
        return false;


    //When user is not touching Screen destroy the
    //mouseJoint/set to null
    if(ran == false){

    world.destroyJoint(joint);
    joint = null;}


    ran = false;
    return true;
}



////////////////////////////////

/////////////////////////////////

    if(!world.isLocked() && world.getBodyCount() > 0 ){

        for(int i = 0; i <bodiesToRemove.size; i++){

            Body b = bodiesToRemove.get(i);

            if(b == null){
                bodiesToRemove.removeIndex(i);
                continue;
            }
            world.destroyBody(b);
            ran = true;
            bodiesToRemove.removeIndex(i);

        }

        }else{

            bodiesToRemove.clear();
        }

    ////////////////////////////////////////////////////////////

Box2D引发一些奇怪的错误,这不是其中之一。

我假设您正在使用LibGDX,基本上发生的是由于Box2D导致的崩溃(我还假设它弹出时说“ java或任何停止响应的东西”),当OpenAL关闭时应用程序退出时,会抛出此错误流和清理资源。 不用太担心。

在销毁尸体之前,请确保检查世界是否已锁定,这通常会引发错误并根据您卸下尸体的方式打印一条清晰的消息告诉您。

if(!world.isLocked())
    // do clean up code here

您不需要清理局部作用域内的变量,也不需要清除主体内部的userdata作为主体,因为它在引用中将不再存在(除非您将其存储在其他位置)。

因此,正确的代码应如下所示:

if(!world.isLocked()){
    for(int i = bodiesToRemove.size - 1; i--){
        Body b = bodiesToRemove.get(i);
        if(b == null){
            bodiesToRemove.removeAt(i);
            continue;
        }
        world.destroyBody(b);
        bodiesToRemove.removeAt(i);
    }
}

您还需要在迭代过程中清除列表,这不是一个好主意。

编辑

我能想到的唯一导致此问题的其他事情就是尝试删除实际上不在世界物体列表中的物体。

请尝试以下操作:

// Ensure world is not locked AND that there is even bodies in the world
if(!world.isLocked() && world.getBodyCount() > 0){
    for(int i = bodiesToRemove.size - 1; i--){
        Body b = bodiesToRemove.get(i);
        if(b == null){
            bodiesToRemove.removeAt(i);
            continue;
        }
        world.destroyBody(b);
        bodiesToRemove.removeAt(i);
    }
}else{
    // There is no bodies in the world, so the bodies in our list are just
    // random memory hogs, leave them for the GC by clearing the list
    bodiesToRemove.clear();
}

编辑

如OP所述,问题在于以下代码块:

私人QueryCallback queryCallback = new QueryCallback(){

@Override
public boolean reportFixture(Fixture fixture) {
    if(fixture.getBody() == chest){
        //add to remove list
        bodiesToRemove.add(chest);
    }
    if (fixture.testPoint(tmp.x, tmp.y)){
        reportFixture = fixture.getBody();
    }
    if (!fixture.testPoint(tmp.x, tmp.y))
        return false;
    //assigning bodyB to fixture 
    jointDef.bodyB = fixture.getBody();
    jointDef.target.set(fixture.getBody().getWorldCenter());
    //jointDef.target.set(tmp.x, tmp.y);
    joint = (MouseJoint) world.createJoint(jointDef);
    return false;
}

};

更具体地说,这一行:

    joint = (MouseJoint) world.createJoint(jointDef);

查询回调在世界步骤中触发。 在Box2D中,不能在世界步骤中创建或破坏实体,装置和关节。

您必须在此方法之外创建它,最简单的方法是通过标志。 将标志设置为true,然后将灯具的实例存储在某处,并在外部使用该标志和灯具在游戏循环中处理它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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