2013-12-01 4 views
0

RayWenderlich tutorial У меня возникла проблема с созданием блока, который заставляет его отскакивать. Но самая неприятная вещь заключается не в том, чтобы обнаружить столкновение между пулей и кирпичом. Теперь пуля проходит мимо кирпича, как будто этого не существует.Sprite Kit Узел не обнаруживает столкновение, а не подпрыгивает

Вот определение пули и кирпича: пули:

bullet = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:kBulletSize]; 
    bullet.name = kShipFiredBulletName; 
    bullet.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bullet.frame.size]; 
    bullet.physicsBody.dynamic = YES; 
    bullet.physicsBody.restitution = 1.0; 
    bullet.physicsBody.affectedByGravity = NO; 
    bullet.physicsBody.categoryBitMask = kShipFiredBulletCategory; 
    bullet.physicsBody.contactTestBitMask = kInvaderCategory; 
    bullet.physicsBody.collisionBitMask = 0x0; 

Кирпич:

SKNode* rebote; 

rebote = [SKSpriteNode spriteNodeWithColor:[SKColor orangeColor] size:kBouncetSize]; 
rebote.position = CGPointMake(550, 500); 
rebote.name = @"kBounceBlock"; 
rebote.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rebote.frame.size]; 
rebote.physicsBody.restitution = 1.0; 
rebote.physicsBody.friction = 0.0; 
rebote.physicsBody.dynamic = NO; 
rebote.physicsBody.affectedByGravity = YES; 
rebote.physicsBody.categoryBitMask = kShipFiredBulletCategory; 
rebote.physicsBody.contactTestBitMask = kInvaderCategory; 
rebote.physicsBody.collisionBitMask = 0x0; 

[self addChild:rebote]; 

А вот метод обнаружения столкновения:

-(void)handleContact:(SKPhysicsContact*)contact 
{ 
    // Ensure you haven't already handled this contact and removed its nodes 
    if (!contact.bodyA.node.parent || !contact.bodyB.node.parent) 
     return; 

    NSArray* nodeNames = @[contact.bodyA.node.name, contact.bodyB.node.name]; 
    if ([nodeNames containsObject:kShipName] && [nodeNames containsObject:kInvaderFiredBulletName]) 
    { 
     // Invader bullet hit a ship 
     [self runAction:[SKAction playSoundFileNamed:@"ShipHit.wav" waitForCompletion:NO]]; 
     //1 
     [self adjustShipHealthBy:-0.334f]; 

     if (self.shipHealth <= 0.0f) 
     { 
      //2 
      [contact.bodyA.node removeFromParent]; 
      [contact.bodyB.node removeFromParent]; 
     } 
     else 
     { 
      //3 
      SKNode* ship = [self childNodeWithName:kShipName]; 
      ship.alpha = self.shipHealth; 

      if (contact.bodyA.node == ship) 
       [contact.bodyB.node removeFromParent]; 
      else 
       [contact.bodyA.node removeFromParent]; 
     } 
    } 
    else if ([nodeNames containsObject:kInvaderName] && [nodeNames containsObject:kShipFiredBulletName]) 
    { 
     NSLog(@"Contacto entre bala e Invader."); 

     // Ship bullet hit an invader 
     [self runAction:[SKAction playSoundFileNamed:@"InvaderHit.wav" waitForCompletion:NO]]; 
     [contact.bodyA.node removeFromParent]; 
     [contact.bodyB.node removeFromParent]; 
     //4 
     [self adjustScoreBy:100]; 
    } 

    if ([nodeNames containsObject:@"kBounceBlock"]) 
     NSLog(@"Contacto entre el cuerpo naranja !!"); 
} 

Whaat я делать не так? Я определил свойство реституции в пуле и в кирпиче. Кирпич не является динамическим, и оба находятся в одной и той же «collisionBitMask».

Я довольно потерян. Заранее благодарен

ответ

4

Настроить надлежащим образом contactTestBitMask и collisionBitMask за Brick и Bullet.

По некоторым причинам у вас есть collisionBitMask, установленный на 0x0, что означает, что узел не столкнется ни с каким другим объектом.

Кроме того, вы указали неправильный categoryBitMask для Brick (то же, что и для Bullet). Вы должны создать для него отдельную категорию:

bullet.physicsBody.categoryBitMask = kShipFiredBulletCategory; 
bullet.physicsBody.contactTestBitMask = kBrickCategory; 
bullet.physicsBody.collisionBitMask = kBrickCategory; 


rebote.physicsBody.categoryBitMask = kBrickCategory; 
rebote.physicsBody.contactTestBitMask = kShipFiredBulletCategory; 
rebote.physicsBody.collisionBitMask = kShipFiredBulletCategory; 
+0

Спасибо, что ваши изменения отлично работают. Теперь я могу обнаружить столкновение между пулей и кирпичом. Теперь мы должны работать, чтобы пуля могла отскочить, когда она касается кирпича. Теперь я могу обнаружить столкновение, но пуля покроет кирпич. –

+0

Как вам переместить пулю? Используйте 'applyForce', чтобы переместить его –

+2

Обратите внимание, что это * неверно *, если вы хотите * обнаружить * столкновение между двумя телами, в соответствии с исходным вопросом. 'collisionBitMask' - это маска, с помощью которой можно увидеть, будут ли взаимодействовать два физических тела, а не будет вызываться' -handleContact: '. Для этого используйте * contactBitMask *. – jemmons

2

categoryBitMask Здесь вы назначаете категорию (или категории), к которой принадлежит «узел». contactTestBitMask - это то, где вы позволяете узлу знать, какие другие узлы он должен запускать -handleContact:, когда он сталкивается с ними.

Вы указываете оба узла выше contactTestBitMask из kInvaderCategory. Это означает, что если любой из этих узлов сталкивается с узлом, который имеет categoryBitMask из kInvaderCategory, их метод -handleContact: будет вызываться. Но ни один из ваших узлов не имеет categoryBitMaskkInvaderCategory, так что этого никогда не произойдет.

Если вы, к примеру, чтобы дать вашему rebote Узел contactTestBitMask из kShipFiredBulletCategory, то это будет вызывать -handleContact: всякий раз, когда bullet узел столкнулся с ним, потому что bullet узел имеет categoryBitMask из kShipFiredBulletCategory.

Смежные вопросы