【问题标题】:-[SKScene didBeginContact] executing multiple times-[SKScene didBeginContact] 执行多次
【发布时间】:2015-08-15 04:08:27
【问题描述】:

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

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

【问题讨论】:

    标签: ios objective-c sprite-kit skscene


    【解决方案1】:

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

    1. 太空岩石X和盾1
    2. 太空岩石X和盾2

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

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

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

    进入...

    [firstBody.node removeFromParent];
    

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


    接下来,转这个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如果您尝试添加nil 节点,Xcode 实际上会因异常而中断。因此,如果self.shieldnil,则该表达式将始终计算为NO

    【讨论】:

    • 当我进入 ![self.children containsObject:self.shield] 部分时,我在第一个盾牌加电后不再获得盾牌。这样做只能用一次。
    • @Exprosul 是的。 这就是重点。如果你有不止一个盾牌,那么它不应该在上面再做第二个盾牌。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多