操作 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
这将影响你操作位域的方式。它可能是有用的(例如)表明物理体(例如炸弹)已经以某种方式发生了变化(例如它可能已经获得了另一类别的超级能力,你可能会检查某个物体(一个外星人的母亲)