2015-11-06 99 views
1

我正在使用sprite kit創建遊戲,但在碰撞中使用時似乎遇到bodyWithTexture問題。 bodyWithRectanglecircleOfRadius工作正常,但是當我使用bodyWithTexture它看起來像didBeginContact方法被多次調用。Sprite Kit Objective 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正常工作,但不與bodyWithTexture? – Hunter23

回答

0

如果您遇到多重碰撞,例如。 didBeginContact被稱爲多次,你有幾個選項...

沒有看你的代碼,可以說你有一個球員和一塊石頭。每當玩家與岩石發生碰撞時,您都要移除岩石。所以,你從父母那裏除去了岩石。但在此之前,你讓你的代碼這種變化(僞代碼):

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

另一種方法是子類SKSpriteNode並作出巖類,並創建一個自定義布爾屬性,這將有一次改變其值第一次碰撞發生。但這只是不必要的併發症:

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"); 
} 

} 

希望它可以幫助