2012-11-08 66 views
1

在此先感謝您的幫助!刪除Box2D機構崩潰AndEngine

我正在構建打磚塊/突圍風格的遊戲,並且由於身體移除(至少這是我懷疑問題所在)的原因而遇到了一些問題。當我運行遊戲時,大部分時間一切正常,但是偶爾遊戲會崩潰。在這次事故中,所有附着在屍體上的精靈都消失了,任何沒有屍體的精靈都留在了屏幕上。沒有LogCat錯誤,但FPS的速度急劇下降。另外,我注意到有時聯繫人在聯繫人偵聽器中的代碼被觸發之前被註冊了兩次(您可以在下面的ContactListener中看到我在哪裏實現了日誌文件輸出)。

在遊戲中,我使用的是螺栓,而不是磚,下面列出了用於生成螺栓的代碼。之後,我展示瞭如何使用ContactListener,然後給出了刪除body/sprite組合的代碼。任何幫助或建議,非常感謝!

感謝,

亞當

創建它們接觸時將被刪除身體/精靈項目。

//BOLTS 
    final FixtureDef boltFixtureDef = PhysicsFactory.createFixtureDef(1, 1.0f, 0.1f); 
    final Body[] boltBody=new Body[BOLT_NUMBER]; 
    final Sprite[] boltSprite=new Sprite[BOLT_NUMBER]; 
    final PhysicsConnector[] facePhysicsConnector= new PhysicsConnector[BOLT_NUMBER]; 
    String[] bodyNames=new String[BOLT_NUMBER]; 

     for(int i=0; i<BOLT_NUMBER; i++){ 
      boltSprite[i] = new Sprite(-100,-100, sceneManager.mBolt, sceneManager.activity.getVertexBufferObjectManager()); 
      boltSprite[i].setCullingEnabled(true); 
      boltBody[i] = PhysicsFactory.createBoxBody(mPhysicsWorld, boltSprite[i], BodyType.KinematicBody, boltFixtureDef); 
      mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(boltSprite[i], boltBody[i], true, true)); 
      bodyNames[i]="bolt"+Integer.toString(i); 
      boltBody[i].setUserData(bodyNames[i]); 
      facePhysicsConnector[i] = mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(boltSprite[i]); 
      boltBody[i].setTransform(xLocations[i]/PMR, yLocations[i]/PMR, 0);} 

      for(int i=0; i<BOLT_NUMBER; i++){  
       scene.attachChild(boltSprite[i]);} 

的ContactListener:

final ContactListener contact = new ContactListener(){ 

    @Override 
    public void postSolve(Contact contact, ContactImpulse impulse) { 

     String a = (String) contact.getFixtureA().getBody().getUserData(); 
     String b = (String) contact.getFixtureB().getBody().getUserData(); 
     if(a != null && b != null) { 
      for(int i=0; i<BOLT_NUMBER; i++){ 
       if(a.equals("wrench") && b.equals(facePhysicsConnector[i].getBody().getUserData()) || 
          a.equals(facePhysicsConnector[i].getBody().getUserData()) && b.equals("wrench")) { 
           //boltCollision[i]=true; 
        Log.i("contact","bolt contact" + i); 
           myDestroyer(facePhysicsConnector[i], true); 
           Log.i("contact","bolt POSTcontact" + i);} 

       else if((a.equals("wrench") && b.equals("paddle")) || 
         (a.equals("paddle") && b.equals("wrench"))) { 
        Log.i("contact","paddle contact"); 
         SpringNoise=true;} 

       else if((a.equals("wrench") && b.equals("door")) || 
         (a.equals("door") && b.equals("wrench"))) { 
        Log.i("contact","door contact"); 
          WoodNoise=true;} 
      }} 

    } 
    @Override 
    public void endContact(final Contact contact) {} 

    @Override 
    public void beginContact(Contact contact) {} 

    @Override 
    public void preSolve(Contact contact, Manifold oldManifold) {} 
     }; 

這裏是能清除體內/精靈組合代碼:

private void myDestroyer(final PhysicsConnector facePhysicsConnector2, final Boolean bodyToo){ 
      if(killingInProcess == false){ 
        killingInProcess = true; 
        //final PhysicsConnector facePhysicsConnector2 = mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(myShape); 
        sceneValue.engine.registerUpdateHandler(new IUpdateHandler(){ 
          @Override 
          public void onUpdate(float pSecondsElapsed) { 
           sceneValue.engine.unregisterUpdateHandler(this); 
           sceneValue.engine.runOnUpdateThread(new Runnable(){ 
                @Override 
                public void run() { 
                 Log.i("contact","removing bolt"); 
                  mPhysicsWorld.unregisterPhysicsConnector(facePhysicsConnector2); 
                  Vibrator v = (Vibrator) sceneValue.activity.getSystemService(Context.VIBRATOR_SERVICE); 
                  //myFixture.getBody().destroyFixture(myFixture); 
                if(bodyToo == true){ 
                    mPhysicsWorld.destroyBody(facePhysicsConnector2.getBody()); 
                } 
                facePhysicsConnector2.getShape().registerEntityModifier(new ParallelEntityModifier(new RotationModifier(3,180,0), 
                new ScaleModifier(3, 1, 0))); 
                sceneValue.mBlockSound.play(); 
                v.vibrate(75); 

                //mScene.detachChild(mySprite); 
                System.gc(); 
                killingInProcess = false; 
                } 
              }); 
          } 
          @Override 
          public void reset() { 
          } 
        });  
      }} 

回答

1

我不知道的崩潰問題,但我做的知道爲什麼拆除屍體太晚了。

方法postSolve是從UpdaeThread中調用的。但不是在那裏刪除身體,而是註冊另一個更新處理程序(所以它的代碼會在下一次遊戲更新中運行)。在此代碼中,您在runOnUpdateThread中運行另一個代碼,以便在下一次遊戲更新中再次運行。你跳過2個更新無故:)這可能會造成問題(可能它)

我建議你解決這個問題,這個查找另一個問題(這可能嚴重,它很容易解決)

+0

感謝您的建議!我將所有內容都從endCollision()移到了postSolve()中,因爲它在endCollision()中註冊了LogCat中的兩個碰撞,但是隻有一個來自postSolve()。你知道這是爲什麼嗎?謝謝 – user1809357

+0

我在這裏閱讀了'ContactListener'回調:http://code.google.com/p/andenginephysicsbox2dextension/source/browse/src/com/badlogic/gdx/physics/box2d/ContactListener.java看起來你需要使用'beginContact'。 – Jong

+0

再次感謝,但不幸的是,如果我使用beginContact(),身體不會相互反彈,他們只是通過對方運行。 – user1809357

1

我米不確定,但我認爲這個問題可能是在你刪除精靈。我遇到了這個問題,現在我試圖殺死像這樣的更新處理程序(更新處理IUpdateHandler中的方法):

   final PhysicsConnector physicsConnector = physicsWorld 
         .getPhysicsConnectorManager().findPhysicsConnectorByShape(
           body); 
       body.clearEntityModifiers(); 
       physicsWorld.unregisterPhysicsConnector(physicsConnector); 
       physicsWorld.destroyBody(physicsConnector.getBody()); 
       scene.detachChild(body); 
       activity.getEngine().unregisterUpdateHandler(this);