2016-05-30 25 views
2

我有4個SpriteNodes在屏幕上,我想不相互彈開,而是流過對方,同時保持一定的SpriteNodes碰撞和屏幕邊框。我已宣佈的類別爲所有這些:SpriteKit - 讓某些SpriteNodes不會發生衝突,而無需禁用它們的物理機構

let BCategory : UInt32 = 0x1 << 0 
let B2Category : UInt32 = 0x1 << 1 
let B3Category : UInt32 = 0x1 << 2 
let B4Category : UInt32 = 0x1 << 3 
let BotCategory : UInt32 = 0x1 << 4 
let PadCategory : UInt32 = 0x1 << 5 
let WallCategory : UInt32 = 0x1 << 6 

並補充位掩碼以及:

b.physicsBody!.categoryBitMask = BCategory 
    b2.physicsBody!.categoryBitMask = B2Category 
    b3.physicsBody!.categoryBitMask = B3Category 
    b4.physicsBody!.categoryBitMask = B4Category 

    p.physicsBody!.categoryBitMask = PadCategory 
    wall.categoryBitMask = WallCategory 
    bot.physicsBody?.categoryBitMask = BotCategory 

    b.physicsBody?.contactTestBitMask = BotCategory | PadCategory 
    b2.physicsBody?.contactTestBitMask = BotCategory | PadCategory 
    b3.physicsBody?.contactTestBitMask = BotCategory | PadCategory 
    b4.physicsBody?.contactTestBitMask = BotCategory | PadCategory 

除了檢查的SpriteNodes之間的碰撞,我想通過碰撞:

func didBeginContact(contact: SKPhysicsContact) { 

是否有可能將所有的b的的(b,B2,B3,B4)與對,牆壁,和機器人發生碰撞而不是彼此之間?很感謝任何形式的幫助!

編輯:時遇到的問題是,由B的表示的SpriteNodes(B,B2,B3,B4)的反彈彼此的。我希望每個b都只能反彈BotCategory和PadCategory中包含的SpriteNodes,並且滑過/穿過其他b。

+0

什麼問題?你實際上沒有說過發生了什麼。 – Fogmeister

+0

@Fogmeister謝謝!我會編輯我的問題,以澄清 – hb22

回答

3

你需要指定的physicsBodies以及類/非接觸式口罩collisionBitMask。所有位默認爲ON。因此,像這樣:

b.physicsBody?.collisionBitMask = BotCategory | PadCategory

+0

完美的作品!謝謝! – hb22

2

你已經得到混合起來碰撞接觸之間。碰撞是當兩個物理實體碰撞並相互反彈時。碰撞完全由遊戲引擎處理。你只需要設置必要的collisionBitMask

一個聯繫人是當精靈套件遊戲引擎告訴你代碼,2個物理機構已經聯繫。然後,您可以使其爆炸,更新樂譜等。如果沒有您接觸到聯絡人的通知,兩個人可能會發生碰撞,或者他們可以在沒有碰撞的情況下進行聯繫。您必須設置contactTestBitMask,將程序設置爲physicsWorld.contactDelegate,並實現didBeginContact/didEndContact函數中的一個或兩個。

無論2體碰撞由collisionBitMask控制。默認情況下,它被設置爲UInt32.Max,即一切都會發生衝突。給定2個身體A和B,身體A可能與身體B碰撞,即從身體B反彈,但身體B 與身體A碰撞,即不受碰撞影響。

你的碼是否被通知2機構進行接觸是由contactTestBitMask控制。默認情況下它被設置爲0,即沒有註冊聯繫人。給定2個機構A和B,您只需將body A的contactTestBit掩碼設置爲bodyB的類別,以便註冊2之間的所有聯繫人。

我發現這個功能很有用,檢查您在場景中有什麼樣的碰撞和接觸:

func checkPhysics() { 

     // Create an array of all the nodes with physicsBodies 
     var physicsNodes = [SKNode]() 

     //Get all physics bodies 
     enumerateChildNodesWithName("//.") { node, _ in 
      if let _ = node.physicsBody { 
       physicsNodes.append(node) 
      } else { 
       print("\(node.name) does not have a physics body so cannot collide or be involved in contacts.") 
      } 
     } 

     //For each node, check it's category against every other node's collion and contctTest bit mask 
     for node in physicsNodes { 
      let category = node.physicsBody!.categoryBitMask 
      // Identify the node by its category if the name is blank 
      let name = node.name != nil ? node.name : "Category \(category)" 

      if category == UInt32.max {print("Category for \(name) does not appear to be set correctly as \(category)")} 

      let collisionMask = node.physicsBody!.collisionBitMask 
      let contactMask = node.physicsBody!.contactTestBitMask 

      // If all bits of the collisonmask set, just say it collides with everything. 
      if collisionMask == UInt32.max { 
       print("\(name) collides with everything") 
      } 

      for otherNode in physicsNodes { 
       if (node != otherNode) && (node.physicsBody?.dynamic == true) { 
        let otherCategory = otherNode.physicsBody!.categoryBitMask 
        // Identify the node by its category if the name is blank 
        let otherName = otherNode.name != nil ? otherNode.name : "Category \(otherCategory)" 

        // If the collisonmask and category match, they will collide 
        if ((collisionMask & otherCategory) != 0) && (collisionMask != UInt32.max) { 
         print("\(name) collides with \(otherName)") 
        } 
        // If the contactMAsk and category match, they will contact 
        if (contactMask & otherCategory) != 0 {print("\(name) notifies when contacting \(otherName)")} 
       } 
      } 
     } 

只是把它與checkPhysics()建立物理後,它會列出該機構碰撞併爲此與您聯繫將被通知。

+0

非常感謝您的詳細解答!我遇到的問題涉及試圖禁止某些SpriteNode彼此碰撞(碰撞檢測已經按順序),並通過上述答案解決 – hb22

相關問題