2015-11-06 2 views
1

Я создаю игру с использованием комплекта спрайтов, но у меня, кажется, есть проблемы с bodyWithTexture при использовании его с коллизиями. bodyWithRectangle и circleOfRadius Работайте хорошо, но когда я использую bodyWithTexture, это выглядит как метод didBeginContact, который вызывается более одного раза.Sprite Kit Цель C

вот пример кода я использую

-(SKNode *) createPlayer 
{ 

    level3Player = [SKNode node]; 
    player3Sprite = [SKSpriteNode spriteNodeWithImageNamed:@"character.png"]; 
    level3Player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:player3Sprite.size.width/2]; 
    level3Player.physicsBody.categoryBitMask = playerCategory3; 
    level3Player.physicsBody.contactTestBitMask = platformCategory3 | rockCategory; 

    [level3Player setPosition:CGPointMake(self.size.height/2, screenHeightL3 *11)]; 
    level3Player.physicsBody.affectedByGravity = NO; 
    player3Sprite.physicsBody.dynamic = YES; 
    level3Player.zPosition = 2; 
    [level3Player setScale:0.6]; 


    [level3Player addChild:player3Sprite]; 

    return level3Player; 

} 


-(void) addRocksL3 
{ 

    int randomNumber = arc4random_uniform(300); 

    rock1 = [SKSpriteNode spriteNodeWithImageNamed:@"AsteroidFire.png"]; 
    rock1.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:rock1.size.width/2]; 
    rock1.position = CGPointMake(self.size.width * 3, randomNumber); 
    rock1.physicsBody.categoryBitMask = rockCategory; 
    rock1.physicsBody.contactTestBitMask = playerCategory3; 
    rock1.physicsBody.dynamic = NO; 
    rock1.physicsBody.affectedByGravity = NO; 
    rock1.zPosition = 2; 
    [rock1 setScale:0.3]; 

    [foregroundLayerL3 addChild:rock1]; 


    [self addChild:rock1]; 

} 



-(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((secondBody.categoryBitMask == platformCategory3) | redPlatformCategory) 
    { 

     level3Player.physicsBody.velocity = CGVectorMake(0, 100); 
     level3Player.physicsBody.affectedByGravity = YES; 

     player3Sprite.texture = [SKTexture textureWithImageNamed:@"goo5.png"]; 

     SKAction *sound1 = [SKAction playSoundFileNamed:@"squish.wav" waitForCompletion:NO]; 
     [self runAction:sound1]; 

     gestureRec3.enabled = YES; 
    } 


    if(secondBody.categoryBitMask == rockCategory) 
    { 
     gestureRec3.enabled = YES; 
     playerL3.physicsBody.velocity = CGVectorMake(0, 200); 
     SKAction *playSound = [SKAction playSoundFileNamed:@"Hurt.wav" waitForCompletion:NO]; 
     [self runAction:playSound]; 
     hitCountL3++; 
    } 

    switch (hitCountL3) 
    { 

     case 1: 
      [health1Level3 removeFromParent]; 
      [self healthNodelevel31]; 

      break; 

     case 2: 
      [hit1L3 removeFromParent]; 
      [self healthNodeLevel32]; 

      break; 

     case 3: 
      [hit2L3 removeFromParent]; 

      player3Sprite.texture = [SKTexture textureWithImageNamed:@"splat.png"]; 
      [self gameOverSplatLevel3]; 
      didDie3 = true; 
      SKAction *playSplat = [SKAction playSoundFileNamed:@"splat.wav" waitForCompletion:NO]; 
      [self runAction:playSplat]; 

      break; 
    }  

, когда я использую этот код моего персонаж будет иногда принимать 1 хит, а иногда принимает все 3 хита, когда я сталкиваюсь с породой. Я мог бы использовать circleOfRadius, который отлично работает, но это не то, что я действительно ищу. Есть ли в любом случае я мог бы использовать bodyWithTexture, чтобы мой персонаж принимал только 1 удар каждый раз?

+4

Это не выглядит как действительный код проверки битовой. – trojanfoe

+0

Откуда берутся cirlceOfRadius или bodyWithRectangle? Вы даже не показываете, как вы создаете свой узел символов. –

+0

Просто добавил мои персонажи и методы рок. Я поставил NSLogs во все мои столкновения, и, похоже, код работает. как я уже сказал, столкновение, похоже, отлично работает с bodyWithRect/circeOfRadius, но не с телом с телом? – Hunter23

ответ

0

Если вы столкнулись с несколькими столкновениями, например. didBeginContact вызывается несколько раз, у вас есть несколько вариантов ...

Не глядя на свой код, скажем, у вас есть игрок и скала. Каждый раз, когда игрок сталкивается с камнем, вы хотите удалить камень. Итак, вы удаляете камень из своего родителя. Но до этого, вы сделаете это изменение в коде (псевдо-код):

if([rockNode parent]){ 
    [rockNode removeFromParent]; 
} 

Другой способ будет подкласс SKSpriteNode и сделать класс Rock и сделать заказ булево свойство, которое изменит свое значение один раз, когда происходит первое столкновение. Но это просто лишнее осложнение:

if(rockNode.canCollide){ 
    [rockNode removeFromParent]; 
    rockNode.canCollide = NO; 
} 
+0

приветствует ответ, но я, наконец, понял способ остановить didBeginContact, вызываемый несколько раз. [self performSelector: @selector (hitMe) withObject: self afterDelay: 3.0], похоже, сделал трюк для меня. – Hunter23

0

У меня было много проблем с правильным количеством столкновений. Иногда он получал бы один, иногда нет. Поэтому я попробовал это, и он работает. Единственное, что нужно изменить, это метод didBeginContact.

Я полагаю, что вы объявили категории, как это:

//define collision categories 
static const uint32_t category1 = 0x1 << 0; 
static const uint32_t category2 = 0x1 << 1; 
static const uint32_t category3 = 0x1 << 2; 

Попробуйте заменить код в didBeginContact с этим. Я помню, что правильные столкновения, наконец, приступили к работе после того, как я это сделал.

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

SKNode *newFirstBody = contact.bodyA.node; 
SKNode *newSecondBody = contact.bodyB.node; 

uint32_t collision = newFirstBody.physicsBody.categoryBitMask | newSecondBody.physicsBody.categoryBitMask; 

if (collision == (category1 | category2)) 
{ 
    NSLog(@"hit"); 
} 

} 

Надеется, что это помогает