2014-04-01 50 views
0

在我的遊戲中,我有一些怪物和我的英雄。當我火了一些子彈我刪除碰撞或者與怪物或接地體機構,並還增加了一個定時器事件刪除子彈作爲如何在遊戲中發射時同步去除b2bodies

-(void) removeProjectile:(CCPhysicsSprite*)projectile{ 
     dispatch_time_t removeProjectile = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC)); 
    dispatch_after(removeProjectile, dispatch_get_main_queue(), ^(void){ 
     int i; 

     for(i=0;i<deadBodyCount;i++) 
     { 
      if(deadBodies[i] == projectile.b2Body) 
      { 
       break; 
      } 
     } 
     if(i==deadBodyCount) 
     { 
      deadBodies[deadBodyCount]=projectile.b2Body; 
      deadBodyCount++; 
     } 
    }); 
} 

,但會發生什麼我的代碼崩潰,不知道。請幫幫我。如果你有任何方法來做到這一點。 我在

-(void)removeDeadBodies{ 
for (int i=0; i<deadBodyCount; i++) { 
    if(deadBodies[i]){ 
     if([self getPSTag:deadBodies[i]]==3){ 
      CCPhysicsSprite *temp=(CCPhysicsSprite *)deadBodies[i]->GetUserData(); 
      NSLog(@"%@",temp); 
      [[self getChildByTag:kTagParentNode]removeChild:temp cleanup:YES]; 
     } 
     else if([self getPSTag:deadBodies[i]]==2){ 
      for (int j=0; j<monsterCount; j++) { 
       if (monsters[j].b2Body==deadBodies[i]) { 
        [[self getChildByTag:kTagParentNode]removeChild:monsters[j] cleanup:YES]; 
        monsters[j]=NULL; 
       } 
      } 
     } 
     _world->DestroyBody(deadBodies[i]); 
     deadBodies[i]=NULL;} 
    } 
    deadBodyCount=0; 
    } 

-(int)getPSTag:(b2Body *)body{ //physics sprite tag value from a b2Body 
CCPhysicsSprite *sprite=(CCPhysicsSprite*)body->GetUserData(); 
//Here is the error------------------------------------ 
if(sprite) 
    return (int)sprite.tag; 
else 
    return 0; 
} 

去除deadbodies,這是我開始接觸方法

-(void)beginContact:(b2Contact *)contact{ 
b2Body *bodyA=contact->GetFixtureA()->GetBody(); 
b2Body *bodyB=contact->GetFixtureB()->GetBody(); 
int collideCheck=[self checkForCollisionGroups:bodyA And:bodyB]; 
if(!collideCheck) 
    return; 
switch (collideCheck) { 
    case 1: 
     for (int i=0; i<monsterCount; i++) { 
      if(monsters[i].isVisible){ 
       //Checking if Projectile hitting the monster 
       //bodyA is monster and bodyB is projectile 
       if([self getPSTag:bodyA]==2&&[self getPSTag:bodyB]==3){ 
        [monsters[i] monsterHit]; 
        [self doExplosionAtPoint:monsters[i].position]; 

        deadBodies[deadBodyCount++]=monsters[i].b2Body; 

        CCPhysicsSprite *x=(CCPhysicsSprite *)bodyB->GetUserData(); 
        for (int i=0; i<10; i++) { 
         if(deadBodies[i]==x.b2Body) 
          return; 
        } 
        deadBodies[deadBodyCount++]=x.b2Body; 

        [self.top updateScore:100]; 
       }//bodyA is Projectile and bodyB is Monster 
       else if([self getPSTag:bodyA]==3&&[self getPSTag:bodyB]==2){//if one of the   body is projectile 
        [monsters[i] monsterHit]; 
        [self doExplosionAtPoint:monsters[i].position]; 

        CCPhysicsSprite *x=(CCPhysicsSprite *)bodyA->GetUserData(); 
        for (int i=0; i<10; i++) { 
         if(deadBodies[i]==x.b2Body) 
          return; 
        } 
        deadBodies[deadBodyCount++]=x.b2Body; 

        deadBodies[deadBodyCount++]=monsters[i].b2Body; 

        [self.top updateScore:100]; 
       } 
      } 
     } 
     break; 
    case 2: 
     if (jumping==YES) { 
      jumping=NO; 
     } 
     break; 
    case 3: //bullet hitting with any object 
     if([self getPSTag:bodyA]==3){//if one of the body is projectile 
      CCPhysicsSprite *x=(CCPhysicsSprite *)bodyA->GetUserData(); 
      for (int i=0; i<10; i++) { 
       if(deadBodies[i]==x.b2Body) 
        return; 
      } 
      deadBodies[deadBodyCount++]=x.b2Body; 
     } 
     else if ([self getPSTag:bodyB]==3){ 
      CCPhysicsSprite *x=(CCPhysicsSprite *)bodyB->GetUserData(); 
      for (int i=0; i<10; i++) { 
       if(deadBodies[i]==x.b2Body) 
        return; 
      } 
      deadBodies[deadBodyCount++]=x.b2Body; 
     } 
     break; 
    case 4: 
     for (int i=0; i<monsterCount; i++) { 
      if(monsters[i].isVisible){ 
       if((bodyA==monsters[i].b2Body&&bodyB==_heroBody)||(bodyA==_heroBody&&bodyB==monsters[i].b2Body)) { 
        _heroBody->SetLinearVelocity(b2Vec2(-3*hero.scaleX, 5)); 
        lifeCount=[_top updateHealthMeterWithDamage:10]; 
        NSLog(@"collide"); 
        moving=false; 
       } 
      } 
     } 
     break; 
    /*case 6:if([self getPSTag:bodyA]==33){ 
     movingTile.position=((CCSprite*)bodyA->GetUserData()).position; 
      } 
     else 
      movingTile.position=((CCSprite*)bodyB->GetUserData()).position;*/ 
    default: 
     break; 
    } 
} 
+0

與你增加數組deadBodies?它是子彈還是怪物或者兩者兼而有之?你的代碼在哪裏崩潰? – SaffronState

+0

什麼行是崩潰?什麼是錯誤信息?添加一個異常斷點。 – LearnCocos2D

+0

錯誤是「訪問異常不正常」 –

回答

0

我看着你的代碼。我不明白使用removeProjectile:CCPhysicsSprite *)射彈{}方法,而您間接地將這些射彈添加到beginContact()中的deadBodies []中。所以我想在這裏你有兩個指向同一個身體的指針。當你運行removeDeadBodies()for循環時,它實際上首先刪除了body,然後在下一次迭代中,當它再次得到沒有body的懸掛指針時,它會崩潰。

我評論了這一行[self removeProjectile:projectile];在createProjectileAt()方法中。現在一切正常。

我知道實現它可能遲了,但建議,爲了更好地控制你的b2body並安全地從世界刪除,你可以將一個帶數據成員的struct數據類型作爲Sprite和BOOL變量,如isDelete。並使用這個結構作爲body的userdata。所以現在你可以在beginContact()回調中將這個bool變量設置爲YES。在你更新後:tick方法在world-> step結束之後只是遍歷整個body的世界並檢查可以被刪除的BOOL var。你可以安全地刪除屍體。不需要維護一個deadBody數組等,因此不會有任何同步問題。

+0

我正在做deadbodycount = 0,因爲在removeDeadBodies方法中刪除了所有屍體 –

+0

我編輯了我的答案。嘗試一次。並且不要在for循環中設置deadbodycount = 0。因爲在for循環中將其設置爲零將導致循環只運行一次或從不運行。當deadBodies [i]早先已經設置爲NULL時,可能會發生這種情況。 – SaffronState

+0

我沒有在for循環中設置deadbodycount = 0,也許在它之外。覈實。我很欣賞你的回答,但是當我大量開火時,同樣的例外情況也發生在同一點上。 –