操作 contactTest 和 collison bitmasks 以啟用特定的特定聯絡和衝突
對於這個例子,我們將使用 4 個主體,為簡單起見,僅顯示位掩碼的最後 8 位。這 4 個實體是 3 個 SKSpriteNodes,每個都有一個物理主體和一個邊界:
let edge = frame.insetBy(dx: 0, dy: 0)
physicsBody = SKPhysicsBody(edgeLoopFrom: edge)
請注意,’edge’物理主體是場景的物理主體,而不是節點。
我們定義 4 個獨特的類別
let purpleSquareCategory: UInt32 = 1 << 0 // bitmask is ...00000001
let redCircleCategory: UInt32 = 1 << 1 // bitmask is ...00000010
let blueSquareCategory: UInt32 = 1 << 2 // bitmask is ...00000100
let edgeCategory: UInt32 = 1 << 31 // bitmask is 10000...00000000
每個物理主體都分配了它所屬的類別:
//Assign our category bit masks to our physics bodies
purpleSquare.physicsBody?.categoryBitMask = purpleSquareCategory
redCircle.physicsBody?.categoryBitMask = redCircleCategory
blueSquare.physicsBody?.categoryBitMask = blueSquareCategory
physicsBody?.categoryBitMask = edgeCategory // This is the edge for the scene itself
如果正文的 collisionBitMask 中的某個位設定為 1,那麼它會碰撞(彈回)任何在其 categoryBitMask 中位於相同位置的 1
的主體。同樣適用於 contactTestBitMask。
除非你另行指定,否則所有內容都會與其他所有內容發生衝突,並且不會生成任何聯絡人(當任何內容與其他任何內容聯絡時,你的代
purpleSquare.physicsBody.collisonBitMask = 11111111111111111111111111111111 // 32 '1's.
每個位置的每一位都是'1’,所以當與任何其他 categoryBitMask 相比時,Sprite Kit 會發現'1’,因此會發生碰撞。如果你不希望此主體與某個類別發生衝突,則必須將 collisonBitMask 中的正確位設定為 0
它的 contactTestbitMask
設定為所有 0
s:
redCircle.physicsBody.contactTestBitMask = 00000000000000000000000000000000 // 32 '0's
與 collisionBitMask 相同,但反轉除外。
體之間的接觸或碰撞可關斷 (留下現有接觸或碰撞不變)使用:
nodeA.physicsBody?.collisionBitMask &= ~nodeB.category
我們邏輯地將 nodeA 的碰撞位掩碼與 nodeB 的類別位掩碼的反(邏輯 NOT,〜運算子)關閉該位 nodeA 的 bitMask。例如,阻止紅色圓圈與紫色方塊碰撞:
redCircle.physicsBody?.collisionBitMask = redCircle.physicsBody?.collisionBitMask & ~purpleSquareCategory
可以縮短為:
redCircle.physicsBody?.collisionBitMask &= ~purpleSquareCategory
說明:
redCircle.physicsBody.collisonBitMask = 11111111111111111111111111111111
purpleSquareCategory = 00000000000000000000000000000001
~purpleSquareCategory = 11111111111111111111111111111110
11111111111111111111111111111111 & 11111111111111111111111111111110 = 11111111111111111111111111111110
redCircle.physicsBody.collisonBitMask now equals 11111111111111111111111111111110
redCircle 不再與類別為…… 0001(purpleSquare)
的物體發生碰撞
你可以直接設定它,而不是關閉 collsionsbitMask 中的各個位:
blueSquare.physicsBody?.collisionBitMask = (redCircleCategory | purpleSquareCategory)
即 blueSquare.physicsBody?.collisionBitMask = (....00000010 OR ....00000001)
等於 blueSquare.physicsBody?.collisionBitMask = ....00000011
blueSquare 只會與類別或..01 或 .10 的實體發生碰撞
2 個機構之間的觸點或碰撞可以開啟 ON (不影響任何現有的聯絡人或碰撞)在使用任何點:
redCircle.physicsBody?.contactTestBitMask |= purpleSquareCategory
我們邏輯上將 redCircle 的 bitMask 與 purpleSquare 的類別位掩碼相關聯,以開啟redcircle 的 bitMask 中的那個位。這使得 redCircel 的 bitMas 中的任何其他位都不受影響。
你可以確保每個形狀彈回螢幕邊緣,如下所示:
// Make sure everything collides with the screen edge
enumerateChildNodes(withName: "//*") { node, _ in
node.physicsBody?.collisionBitMask |= self.edgeCategory //Add edgeCategory to the collision bit mask
}
注意:
碰撞可以是片面的,即物體 A 可以碰撞(反彈)物體 B,而物體 B 繼續進行,就好像什麼也沒發生過一樣。如果你想讓 2 個物體相互反彈,它們必須被告知要與另一個物體相撞:
blueSquare.physicsBody?.collisionBitMask = redCircleCategory
redcircle.physicsBody?.collisionBitMask = blueSquareCategory
然而,聯絡不是片面的; 如果你想知道物件 A 何時觸控(接觸)物件 B,則就物件 B 設定物件 A 的接觸檢測就足夠了。你不必在物件 B 上為物件 A 設定接觸檢測。
blueSquare.physicsBody?.contactTestBitMask = redCircleCategory
我們不需要 redcircle.physicsBody?.contactTestBitMask= blueSquareCategory
高階用法:
這裡沒有涉及,但物理機構可以屬於多個類別。例如,我們可以將遊戲設定如下:
let squareCategory: UInt32 = 1 << 0 // bitmask is ...00000001
let circleCategory: UInt32 = 1 << 1 // bitmask is ...00000010
let blueCategory: UInt32 = 1 << 2 // bitmask is ...00000100
let redCategory: UInt32 = 1 << 3 // bitmask is ...00001000
let purpleCategory: UInt32 = 1 << 4 // bitmask is ...00010000
let edgeCategory: UInt32 = 1 << 31 // bitmask is 10000...0000000
每個物理主體都分配了它所屬的類別:
//Assign our category bit masks to our physics bodies
purpleSquare.physicsBody?.categoryBitMask = squareCategory | purpleCategory
redCircle.physicsBody?.categoryBitMask = circleCategory | redCategory
blueSquare.physicsBody?.categoryBitMask = squareCategory | blueCategory
他們的 categorybitMasks 現在是:
purpleSquare.physicsBody?.categoryBitMask = ...00010001
redCircle.physicsBody?.categoryBitMask = ...00001010
blueSquare.physicsBody?.categoryBitMask = ...00000101
這將影響你操作位域的方式。它可能是有用的(例如)表明物理體(例如炸彈)已經以某種方式發生了變化(例如它可能已經獲得了另一類別的超級能力,你可能會檢查某個物體(一個外星人的母親)