如何在游戏中射击时同步移除b2体

时间:2014-04-01 08:19:34

标签: iphone cocos2d-iphone box2d

在我的游戏中,我有一些怪物和我的英雄。当我发射一些子弹时,我会在与怪物或地面车身碰撞时移除物体,并且还添加了一个计时器事件来移除子弹

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

这是我的开始联系方式

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

1 个答案:

答案 0 :(得分:0)

我看了你的代码。我不明白使用removeProjectile:CCPhysicsSprite *)projectile {}方法,而间接实际将射弹添加到beginContact()中的deadBodies []。所以我想在这里你有两个指向同一个身体的指针。当你运行removeDeadBodies()for循环时,它实际上首先删除了主体,然后在下一次迭代中再次获得没有主体的悬空指针然后崩溃。

我评论了这一行[self removeProjectile:projectile];在createProjectileAt()方法中。现在一切正常。

我知道实施可能会迟到但是建议,为了更好地保留你的b2Bodies并从世界中安全删除,你可以采用struct数据类型,数据成员为Sprite,BOOL变量为isDelete。并使用此结构作为正文的用户数据。所以现在你可以在beginContact()回调中将这个bool变量设置为YES。并且在你更新时:在world-&gt;步骤结束之后的tick方法只是遍历body的世界并检查可以删除的BOOL var。你可以安全地删除尸体。无需维护一系列deadBodies等。因此不存在任何同步问题。