Ios -[SKScene didBeginContact]执行多次

Ios -[SKScene didBeginContact]执行多次,ios,objective-c,sprite-kit,skscene,Ios,Objective C,Sprite Kit,Skscene,我正在为我的游戏创建一个盾牌加电。它的工作方式是,如果你拍摄一个加电图标,你会获得一个随着时间的推移而过期的盾牌。当一块岩石撞击防护罩时,它会被摧毁,形成碎片。出现的问题是,在游戏过程中,当你击中多个盾牌图标时,产生的碎片数量会显著增加。就好像只有一个护盾时有多个护盾。我该如何解决这个问题 My Code: - (void) didBeginContact:(SKPhysicsContact *)contact{ ... else if (firstBody.cate

我正在为我的游戏创建一个盾牌加电。它的工作方式是,如果你拍摄一个加电图标,你会获得一个随着时间的推移而过期的盾牌。当一块岩石撞击防护罩时,它会被摧毁,形成碎片。出现的问题是,在游戏过程中,当你击中多个盾牌图标时,产生的碎片数量会显著增加。就好像只有一个护盾时有多个护盾。我该如何解决这个问题

My Code: 
- (void) didBeginContact:(SKPhysicsContact *)contact{
         ...
    else if (firstBody.categoryBitMask == CollisionCategoryRocks && secondBody.categoryBitMask == CollisionCategoryShield){
        // Rock hits Shield
        if (!_shield.hidden){
            if (firstBody.categoryBitMask == CollisionCategoryRocks){
                SpaceRockNode *spaceRock = (SpaceRockNode *) firstBody.node;
                [spaceRock removeFromParent];
                [self createDebrisAtPosition:contact.contactPoint];
            } 
        }
    }

    else if ((firstBody.categoryBitMask == CollisionCategoryLaser || firstBody.categoryBitMask == CollisionCategoryPlasmaShot ||firstBody.categoryBitMask == CollisionCategoryProjectile) && secondBody.categoryBitMask == CollisionCategoryShieldIcon){
    // Projectile hits Shield Icon

        if (!self.shieldIsActive){
            self.shield = [ShieldNode shieldAtPosition:CGPointMake(CGRectGetMidX(self.frame)+4, CGRectGetMidY(self.frame)-210)];
            [self addChild:self.shield];
            self.shieldIsActive = YES;
            SKAction *wait = [SKAction waitForDuration:ShieldTimer];
            [self runAction:wait completion:^{
               self.shield.hidden = YES;
               self.shieldIsActive = NO;
            }];
       }
   }
           ...
}

你的问题是,当碎片疯狂地飞出时,会发生两次碰撞:

  • 太空岩石
    X
    和护盾
    1
  • 太空岩石
    X
    和护盾
    2
  • 这会导致
    didBeginContact:
    被调用两次,因此,飞出的碎片是的两倍。

    我要修正的一件事,只是把代码缩短一点,就是修改这个语句

    SpaceRockNode *spaceRock = (SpaceRockNode *) firstBody.node;
    [spaceRock removeFromParent];
    
    if (!self.shieldIsActive) {
        ...
    }
    
    进入

    [firstBody.node removeFromParent];
    
    if (!self.shieldIsActive && ![self.children containsObject:self.shield]) {
        ...
    }
    
    如果您不使用该
    太空岩石
    执行任何其他操作,那么就没有理由将节点制作成太空岩石,只是为了将其用作节点


    接下来,将此
    if
    语句

    SpaceRockNode *spaceRock = (SpaceRockNode *) firstBody.node;
    [spaceRock removeFromParent];
    
    if (!self.shieldIsActive) {
        ...
    }
    
    进入

    [firstBody.node removeFromParent];
    
    if (!self.shieldIsActive && ![self.children containsObject:self.shield]) {
        ...
    }
    
    此修改的语句确保
    self.shield
    self.children
    的成员,然后再将
    self.shield
    添加到
    self.children
    中。
    如果只有一个护罩,则只有一束碎片会飞出


    如果
    self.shield
    设置为
    nil
    (换句话说,它还没有被分配到),
    containsObject:
    方法将计算为
    NO
    ,因为
    self.children
    不包含
    nil
    如果您尝试添加
    nil
    节点,Xcode实际上会异常中断。因此,如果
    self.shield
    nil
    ,则当我输入时,该表达式将始终计算为
    NO

    ![self.shield:self.shield]第一部分在第一个护盾通电后不再获得护盾。这样做只能工作一次。@Exprosul是的。这就是重点。如果你有一个以上的盾牌,那么它不应该在上面做第二个盾牌。