2015-03-02 66 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