2015-03-02 82 views
0

谁能告诉我这是为什么返回错误删除身体的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(); 
     } 

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

回答

2

Box2D会抛出一些奇怪的错误,这不是其中之一。

我假设你正在使用LibGDX,基本上发生了什么是由于Box2D引起的崩溃(我也假设它会弹出“java或其他什么都停止响应”),你看到的这个错误是在应用程序退出时引发的而OpenAL正在关闭流并清理资源。不要太担心。

确保您在检测到世界在销毁机体之前被锁定,它通常会抛出一个错误并打印出一条清晰的信息,告诉您这取决于您移除机构的方式。

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

你并不需要清理内局部范围的变量,或清除身体内的用户数据的,因为它会在参考不再存在(除非您有它保存在其他地方)的身体。

所以正确的代码会是这样的:

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

EDIT

如上所述由OP,问题在于与代码块:

私人QueryCallback queryCallback =新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,并将灯具的实例存储在某个地方,并在游戏循环中使用该标志和灯具在外部处理。

+0

我认为的第一件事就是想要删除正在使用的Body,但是看到AL,放弃它,我的问题是,box2d在与AL相关时会抛出错误?虽然逻辑会让它发送,如果应用程序崩溃,我想问你是否只抛出这个错误“AL lib ....”或由其他人陪同,要知道,从来没有我持续 – 2015-03-02 12:00:42

+1

Box2D不会抛出该错误,实际应用确实如此。它由于崩溃而被抛出,大多数Box2D崩溃导致应用程序挂起,然后CTD,因此AL库没有时间清理。所以它打印这个错误。 – Gibbo 2015-03-02 12:05:33

+0

感谢您的回应没有发生在我身上,看到AL lib放弃他所相信的,原则上哈哈,感谢您的澄清,我认为你的回答是正确的我删除我的 – 2015-03-02 12:09:01