-[SKScene didBeginContact] 执行多次

-[SKScene didBeginContact] executing multiple times

我正在为我的游戏制作护盾道具。它的工作方式是,如果你射击一个加电图标,你会获得一个随着时间的推移而失效的护盾。当一块岩石撞击盾牌时,它会被摧毁并产生碎片。出现的问题是,在游戏过程中,当您点击多个盾牌图标时,产生的碎片数量会显着增加。就好像只有一个盾牌时有多个盾牌一样。我该如何解决这个问题?

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;
            }];
       }
   }
           ...
}

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

  1. Space 岩石 X 和盾牌 1
  2. Space 岩石 X 和盾牌 2

这导致 didBeginContact: 被调用 两次 ,因此,飞出的碎片 是原来的两倍。

为了稍微缩短您的代码,我要解决的一件事是更改此语句...

SpaceRockNode *spaceRock = (SpaceRockNode *) firstBody.node;
[spaceRock removeFromParent];

进入...

[firstBody.node removeFromParent];

如果您不对 Space Rock 做任何其他事情,那么就没有理由将节点变成 space 岩石只是为了将其用作节点。


接下来,将此 if 声明...

if (!self.shieldIsActive) {
    ...
}

进入...

if (!self.shieldIsActive && ![self.children containsObject:self.shield]) {
    ...
}

此修改后的语句确保 self.shieldself.children 的成员,然后再将 self.shield 第二次添加到 self.children 如果只有一个护盾,只会飞出一堆碎片

如果self.shield设置为nil(也就是说还没有赋值),则containsObject:方法将评估为 NO 因为 self.children 不包含 nil. Xcode 如果您尝试并且实际上会出现异常添加一个 nil 节点。因此,如果 self.shieldnil,则该表达式的计算结果将始终为 NO