Sprite Kit collisions for multiple collisions

2019-04-14 22:00发布

I have looked, and have found answers for single collisions, but I am looking for a way to detect more than one type of collision. I am making a game where there are 3 collisions I would like. The user plane colliding with enemy bullets, the user's bullet colliding with the enemy plane (which i have working already), and the enemy bullet and user bullet colliding. I have all the categoryBitMask and contactTestBitMask set up and correct. Here is my delegate method.

 - (void) didBeginContact:(SKPhysicsContact *)contact {

SKPhysicsBody *firstBody, *secondBody;


if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
    firstBody = contact.bodyA;
    secondBody = contact.bodyB;
}
else
{
    firstBody = contact.bodyB;
    secondBody = contact.bodyA;
}

// if user plane hits enemy bullet
if ((firstBody.categoryBitMask == playerShipCategory) &&
    (secondBody.categoryBitMask == enemyBulletCategory)) {

    [self takeDamageByAmount:POINT_INCREMENTER];
    [_enemyBullet removeFromParent];
    SKAction *bounce = [SKAction sequence:@[
                                            [SKAction fadeAlphaTo:.5 duration:.2],
                                            [SKAction fadeAlphaTo:1.0 duration:.2],
                                            [SKAction fadeAlphaTo:.5 duration:.2],
                                            [SKAction fadeAlphaTo:1.0 duration:.2]
                                            ]];
    [_playerPlane runAction:bounce];
}

// if the user bullet hits the enemy bullet
else if ((firstBody.categoryBitMask == bulletCategory) &&
   (secondBody.categoryBitMask == enemyBulletCategory)) {
    [_enemyBullet removeFromParent];
    [_bullet removeFromParent];
}

// if bullet hits enemy ship - THIS ONE WORKS, but none of the others work for some reason
else if ((firstBody.categoryBitMask == bulletCategory) &&
    (secondBody.categoryBitMask == enemyShipCategory)) {

    [self gainPointsByAmoint:POINT_INCREMENTER];
    [self projectile:(SKSpriteNode *)firstBody.node didCollideWithMonster:(SKSpriteNode *)secondBody.node];
}
}

1条回答
叛逆
2楼-- · 2019-04-14 22:48

This should work it's already tested and working

//Define the collider Category

  typedef NS_ENUM(uint32_t, CollisionType) {
    enemyShipCategory        = 0x1 << 0,
    enemyBulletCategory      = 0x1 << 1,
    playerShipCategory       = 0x1 << 2,
    bulletCategory           = 0x1 << 3,
  };


// Set the category that this physics body belongs to 
// and specify which categories of bodies cause intersection 
// notifications with this physics body

  ship.physicsBody.categoryBitMask = playerShipCategory;       
  ship.physicsBody.contactTestBitMask = enemyBulletCategory;

  shipBullet.physicsBody.categoryBitMask = bulletCategory;
  shipBullet.physicsBody.contactTestBitMask = enemyShipCategory | enemyBulletCategory;

  enemy.physicsBody.categoryBitMask = enemyShipCategory;
  enemy.physicsBody.contactTestBitMask = bulletCategory;

  enemyBullet.PhysicsBody.categoryBitMask = enemyBulletCategory;
  enemyBullet.physicsBody.contactTestBitMask = bulletCategory;

// And handle Collisions

- (void)didBeginContact:(SKPhysicsContact *)contact {
  uint32_t collision = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);

  if (collision == (playerShipCategory | enemyBulletCategory)) {
    SKNode *Ship, *bullet;

    if (contact.bodyA.categoryBitMask == playerShipCategory) {
      Ship = contact.bodyA.node;
      bullet = contact.bodyB.node;
    } else {
      Ship = contact.bodyB.node;
      bullet = contact.bodyA.node;
    }

    [self takeDamageByAmount:POINT_INCREMENTER];
    [bullet removeFromParent];

    SKAction *bounce = [SKAction sequence:@[
      [SKAction fadeAlphaTo:.5 duration:.2],
      [SKAction fadeAlphaTo:1.0 duration:.2],
      [SKAction fadeAlphaTo:.5 duration:.2],
      [SKAction fadeAlphaTo:1.0 duration:.2]
    ]];

    [Ship runAction:bounce];
  }

  else if (collision == (bulletCategory | enemyBulletCategory)) {
    [contact.bodyA.node removeFromParent];
    [contact.bodyB.node removeFromParent];
  }

  else if (collision == (bulletCategory | enemyShipCategory)) {
    SKNode *shipBullet, *enemyShip;

    if (contact.bodyA.categoryBitMask == shipBullet) {
      shipBullet = contact.bodyA.node;
      enemyShip = contact.bodyB.node;
    } else {
      shipBullet = contact.bodyB.node;
      enemyShip = contact.bodyA.node;
    }

    [self gainPointsByAmoint:POINT_INCREMENTER];
    [self projectile:shipBullet didCollideWithMonster:enemyShip];
  }
}

Good Luck!!

查看更多
登录 后发表回答