0

問題:只要玩家節點與硬幣節點接觸,遊戲就會在遊戲只有在玩家與邊界碰撞時纔會結束。當玩家節點與另一個節點發生衝突時,遊戲結束時,遊戲只應在玩家與邊界碰撞時結束

輸出結果應該是:玩家應該能夠接觸到硬幣節點並穿過硬幣節點,爲scoreLabel添加一個值。 當前的代碼:

struct ColliderType { 

static let playerCategory: UInt32 = 0x1 << 0 
static let boundary: UInt32 = 0x1 << 1 
static let coinCategory: UInt32 = 0x1 << 2 
static let firstBody: UInt32 = 0x1 << 3 
static let secondBody: UInt32 = 0x1 << 4 

} 

    var gameOver = false 
    var coinInt = 0 

    coin.physicsBody?.categoryBitMask = ColliderType.coinCategory 
    coin.physicsBody?.contactTestBitMask = ColliderType.playerCategory 
    coin.physicsBody?.collisionBitMask = 0 


    player.physicsBody?.categoryBitMask = ColliderType.playerCategory 
    player.physicsBody?.contactTestBitMask = ColliderType.boundary | ColliderType.coinCategory 
    player.physicsBody?.collisionBitMask = ColliderType.boundary 

func didBeginContact(contact:SKPhysicsContact) { 
    var firstBody: SKPhysicsBody 
    var secondBody: SKPhysicsBody 

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 
     firstBody = contact.bodyA 
     secondBody = contact.bodyB 


    } else{ 

     firstBody = contact.bodyB 
     secondBody = contact.bodyA 

    } 

    if firstBody.categoryBitMask == ColliderType.playerCategory && secondBody.categoryBitMask == ColliderType.coinCategory { 
     self.coin.removeFromParent() 
     coinInt += 1 
     coinLabel.text = "\(coinInt)" 
    } 

    gameOver = true 
    self.speed = 0 
    timer.invalidate() 

} 

override func touchesBegan(touches: Set<UITouch> , withEvent event: UIEvent?) { 
    if gameOver == false { 

    self.player.physicsBody?.velocity = CGVectorMake(1, 3) 
    self.player.physicsBody?.applyImpulse(CGVectorMake(0, 12)) 

    } 

} 

UPDATE:

boundary.contactTestBitMask = ColliderType.playerCategory 
    boundary.categoryBitMask = ColliderType.boundary 
    boundary.collisionBitMask = ColliderType.playerCategory 

    coin.physicsBody?.categoryBitMask = ColliderType.coinCategory 
    coin.physicsBody?.contactTestBitMask = ColliderType.playerCategory 
    coin.physicsBody?.collisionBitMask = 0 


    player.physicsBody?.categoryBitMask = ColliderType.playerCategory 
    player.physicsBody?.contactTestBitMask = ColliderType.coinCategory 
    player.physicsBody?.collisionBitMask = ColliderType.boundary 




func didBeginContact(contact:SKPhysicsContact) { 
    let firstBody: SKPhysicsBody 
    let secondBody: SKPhysicsBody 


    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 
     firstBody = contact.bodyA 
     secondBody = contact.bodyB 


    } else{ 

     firstBody = contact.bodyB 
     secondBody = contact.bodyA 

    } 


    if firstBody.categoryBitMask == ColliderType.coinCategory || secondBody.categoryBitMask == ColliderType.coinCategory { 

    self.coin.removeFromParent() 
    self.coinInt += 1 
    self.coinLabel.text = "\(self.coinInt)" 

    }else if firstBody.categoryBitMask == ColliderType.boundary || secondBody.categoryBitMask == ColliderType.boundary { 

    gameOver = true 
    self.speed = 0 
    timer.invalidate() 

} 
} 
+0

關於你的編輯:你的播放器沒有檢查邊界,而是反過來說可能會有些道理。但是,你可能不希望_player_檢查任何聯繫人來簡化事情。 –

回答

2

gameOver = true陳述外didBeginContact所有IFS。換句話說:發生聯繫的那一刻你設置了gameOver = true。

if firstBody.categoryBitMask == ColliderType.coinCategory || secondBody.categoryBitMask == ColliderType.coinCategory { 
    self.coin.removeFromParent() 
    coinInt += 1 
    coinLabel.text = "\(coinInt)" 
} else if firstBody.categoryBitMask == ColiderType.boundary || secondBody.categoryBitMask == ColiderType.boundary { 
    gameOver = true 
    self.speed = 0 
    timer.invalidate() 
} 

可能更接近你想要的。

+0

嗨,對不起,延遲迴復。該代碼看起來正是我所需要的,但是當我測試它時,第一個if語句不起作用,而else if函數的工作方式與它應該一樣。我一直在修改我的代碼,測試不同的方法,看起來它應該完美無缺地工作,但是如果語句目前是不起作用的話。 –

+0

其實它看起來像你應該使用,如果'firstBody.categoryBitMask == ColliderType.coinCategory || secondBody.categoryBitMask == ColliderType.coinCategory',因爲硬幣只檢查它是否與玩家接觸。 –

+0

我將第一個if語句替換爲您提供的第一個if語句,並且我似乎注意到第一個if語句沒有按照其應有的方式發生任何更改。一秒鐘,我會用我現在的代碼更新我的問題。我仍然很快學習,所以我非常感謝你的幫助。 –

1

一個更清潔的方式來編碼didBeginContact,從而降低約與firstBody/secondbody的碴,是:

func didBeginContact(contact: SKPhysicsContact) { 
     let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask 

     switch contactMask { 

     case ColliderType.playerCategory | ColliderType.coinCategory: 
      // player and coin have contacted. We need to get the coin, which is either firstBody or secondBody, to remove it, so assign the corect one to coinNode 
      let coinNode = contact.bodyA.categoryBitMask == ColliderType.coinCategory ? contact.bodyA.node! : contact.bodyB.node! 
      coinNode.removefromParent 
      coinInt += 1 
      coinLabel.text = "\(coinInt)" 

     case ColliderType.playerCategory | ColliderType.boundaryCategory: 
      // player and boundary have contacted 
       gameOver = true 
      self.speed = 0 
      timer.invalidate() 

     default : 
      //Some other contact has occurred 
      print("Some other contact") 
     } 
    } 

只要你喜歡你可以添加儘可能多的case ColliderType.object1 | ColliderType.object2:

+0

唯一的問題是有2個類別被排除的對象 – Knight0fDragon

+0

不確定是否爲真,因爲我們正在測試是否設置了類別中的某些位但設置了掩碼,而不是整個類別(至少這是意圖)。 –

+0

player = 0001,coin = 0010 superpower = 0100如果節點由於擁有超能力而變成0101,那麼玩家|硬幣失敗,因爲你比較0111到0011,但你想讓它通過,並且爲了達到這個目的而必須分支到每一個案例都是荒謬的 – Knight0fDragon

1

(添加一個新的答案,因爲它是基於新的代碼和討論/在OP-問題的變化將使邏輯流有點難以跟隨)

首先,我會進行以下變化到physicBodies:

player.physicsBody?.contactTestBitMask = 0 // or ColliderType.None which would be my stylistic choice 

那麼剩下就看是這樣的。

func didBeginContact(contact:SKPhysicsContact) { 
    let firstBody = contact.bodyA 
    let secondBody = contact.bodyB 

    if firstBody.categoryBitMask == ColliderType.coinCategory || secondBody.categoryBitMask == ColliderType.coinCategory { 
     self.coin.removeFromParent() 
     self.coinInt += 1 
     self.coinLabel.text = "\(self.coinInt)" 
    } else if firstBody.categoryBitMask == ColliderType.boundary || secondBody.categoryBitMask == ColliderType.boundary { 
     gameOver = true 
     self.speed = 0 
     timer.invalidate() 
    } 
} 

的說明: 它不是從提供的代碼self.coin如何引用清楚。我self.coin.removeFromParent()可能沒有太多的意義,因爲你在第一篇文章中寫的幾個硬幣。它可能應該是這樣的,而不是:

if contact.bodyA.categoryBitMask == ColliderType.coinCategory { 
    contact.bodyA.node!.removeFromParent() 
} else if contact.bodyB.categoryBitMask == ColliderType.coinCategory { 
    contact.bodyB.node!.removeFromParent() 
} 

,但我真的考慮返工整個接觸處理成不同的野獸完全如果您計劃在此上下行擴大。

+1

您提供的代碼已解決問題,現在硬幣碰撞功能完美無缺!感謝您的幫助!當我獲得15個聲望時,我會做一個筆記來回到這個帖子,以便我可以投票回答這個問題。 –