防止精灵节点 "stacking" 相互重叠?

Preventing sprite nodes from "stacking" on top of each other?

我正在尝试为我的 iOS spritekit 游戏创建一个护盾强化,它没有刷新当前护盾,而是在顶部堆叠了另一个护盾。我的代码:

    -(void)didMoveToView:(SKView *)view {
               ...
    self.shieldIsActive = NO;
               ...
}
    -(void)didBeginContact:(SKPhysicsContact *)contact{
               ...
   else if (firstBody.categoryBitMask == CollisionCategoryLaser | firstBody.categoryBitMask == CollisionCategoryPlasmaShot |firstBody.categoryBitMask == CollisionCategoryProjectile && secondBody.categoryBitMask == CollisionCategoryShieldIcon){
        // Projectile OR Plasma Shot Or Laser hits Shield Icon
        ShieldIconNode *shieldIcon = (ShieldIconNode *)secondBody.node;
        ShieldNode *shield = [ShieldNode shieldAtPosition:CGPointMake(CGRectGetMidX(self.frame)+4, CGRectGetMidY(self.frame)-210)];
        [shieldIcon removeFromParent];
        if (firstBody.categoryBitMask == CollisionCategoryProjectile){
            ProjectileNode *projectile = (ProjectileNode *)firstBody.node;
            [projectile removeFromParent];
        }
        if (!self.shieldIsActive){
            [self addChild:shield];
            self.shieldIsActive = YES;
        }
        // Remove shield after a period of time. BUG: Adds multiple shields if one is already active
        if (self.shieldIsActive){
            SKAction *wait = [SKAction waitForDuration:ShieldTimer];
            [self runAction:wait completion:^{[shield removeFromParent];}];
            self.shieldIsActive = NO;

... }

让我们替换这个条件:

else if (firstBody.categoryBitMask == CollisionCategoryLaser | firstBody.categoryBitMask == CollisionCategoryPlasmaShot |firstBody.categoryBitMask == CollisionCategoryProjectile && secondBody.categoryBitMask == CollisionCategoryShieldIcon){

通过这个:

else if ((firstBody.categoryBitMask == CollisionCategoryLaser || firstBody.categoryBitMask == CollisionCategoryPlasmaShot || firstBody.categoryBitMask == CollisionCategoryProjectile ) && secondBody.categoryBitMask == CollisionCategoryShieldIcon){

请注意 OR 运算符使用 || 而不是 |

正如 Domsware 指出的那样,在您的第一个 if 语句中,按位 | 需要替换为逻辑 ||(并添加适当的括号)。奇怪的是,由于 | 运算符的优先级低于 == 运算符,因此您的 if 语句可能按预期工作。

此外,您应该考虑 hiding/showing 护盾而不是 Whirlwind 建议的 adding/removing 护盾。

也就是说,有些想法...

  1. if (!self.shieldIsActive)if (self.shieldIsActive)的条件永远是true(除非在代码的其他地方设置了shieldIsActive),这可能会导致不止一个一次在场景中屏蔽
  2. self.shieldIsAction = NO 移动到操作的完成块中将解决此问题

和一些代码...

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