2013-05-14 79 views
0

在我的代碼中,我想摧毀兩個聯繫人中的一個。內beginContact在CCPhysicsSprite以下方法被稱爲:保存要銷燬的接觸體

-(void)contactMade:(CCPhysicsSprite*)contactedSprite { 
int spriteTag1 = self.tag; 
int spriteTag2 = contactedSprite.tag; 

if (((spriteTag1 == 3) && (spriteTag2 == 4)) || ((spriteTag1 == 4) && (spriteTag2 == 3)) { 

    CCPhysicsSprite* heroSprite = (CCPhysicsSprite*)[self getChildByTag:4]; 
    b2World* world; 

    world->DestroyBody(heroSprite.b2Body); 
    heroSprite.b2Body = NULL; 
    [heroSprite.parent removeChild:heroSprite]; 
} 

我得到一個信號SIGABRT指向

b2Assert(m_bodyCount > 0); 

在這個問題上搜索後。我讀到,在時間步後,聯絡主體必須被保存和銷燬。我如何做到這一點,因爲我已經在CCPhyscisSprite中設置了我的聯繫條件。

+0

您需要將要被銷燬的物體添加到數組中,最好是在運行box2d世界步驟的類中。在該步驟之後,銷燬陣列中的所有物體並將其清空。提示:在http://www.koboldtouch.com中,您可以直接在聯繫人回叫方法中銷燬這些身體。 – LearnCocos2D 2013-05-14 10:45:02

回答

1

您可以添加一個標誌(如:isDead ...)到您的物理對象,並在碰撞事件中將該標誌值更改爲TRUE。

-(void) CollisionBegin:(b2Fixture*)target With:(b2Fixture*) source 
{  
    if (target->GetBody()->GetType() == b2_dynamicBody) 
    { 
     yourCustomClass *temp = (yourCustomClass *)target->GetBody()->GetUserData(); 
     temp->isDead = true ; 
    } 
} 

然後在更新函數後,獲取所有物理世界的對象,並通過標誌(Here:isDead)找到該特定對象,並銷燬該對象。

-(void) update: (ccTime) dt 
{ 

    int32 velocityIterations = 8; 
    int32 positionIterations = 3; 

    world->Step(dt, velocityIterations, positionIterations); 

    // remove your box2d object here , after step function 

    for (b2Body *b = world->GetBodyList(); b;) 
    { 
     b2Body *baba = b->GetNext(); 
     if (b->GetUserData() != NULL && b->GetType() == b2_dynamicBody) 
     { 
      yourCustomClass *t = (yourCustomClass *)b->GetUserData(); 
      if (t->isDead) 
      { 
       world->DestroyBody(b); // remove physical body 
       [self removeChild:t];  // remove node from super layer 
      } 
     } 
     b = baba ; 
    } 
} 
+1

這可能會有點慢,如果有大量的世界機構,因爲它是檢查每一個時間步長,大部分的時候它不會找到任何屍體給毀了。將對象添加到列表(std :: set是最好的),然後在時間步驟之後銷燬列表中的任何內容對於大型世界更有效。 – iforce2d 2013-05-17 17:47:12