SpriteKit – 使某些SpriteNodes不会相互碰撞而不禁用它们的物理实体

我有4个SpriteNodes在屏幕上,我想不会互相反弹,而是stream过对方,同时保持与某些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 

并添加了Bitmasks:

  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)与p,wall和bot相互碰撞,而不是彼此之间? 很感谢任何forms的帮助!

编辑:我遇到的问题是由b(b,b2,b3,b4)代表的SpriteNode彼此反弹。 我希望每个b都只反弹BotCategory和PadCategory中包含的SpriteNodes,并滑过/穿过其他b。

您需要指定physicsBodies上的collisionBitMask以及类别/联系人掩码。 这是所有位默认打开。 所以像这样的东西:

b.physicsBody?.collisionBitMask = BotCategory | PadCategory

碰撞联系人之间已经混在一起了。 碰撞是两个物理实体碰撞并相互反弹。 碰撞完全由游戏引擎处理。 你只需要设置必要的collisionBitMask

一个联系是当精灵套件游戏引擎告诉你代码,2个物理机构已经联系。 然后,你可以使一个爆炸,更新分数等2身体可以碰撞,而不通知你的联系,或者他们可以进行接触,而不会发生碰撞。 您必须设置contactTestBitMask,将您的程序设置为physicsWorld.contactDelegate并实现didBeginContact / didEndContact函数中的一个或两个。

collisionBitMask控制两个物体是否collisionBitMask 。 默认情况下,这被设置为UInt32.Max即所有东西都碰撞。 给定2个物体A和B,A物体可能与B物体发生碰撞,也就是反弹B物体,但B物体与A物体发生碰撞,即不受碰撞的影响。

不pipe你的代码是否被通知了2个正在进行联系的主体,都由contactTestBitMask控制。 默认设置为0,即没有联系人被注册。 给定2个主体A和B,您只需将body A的contactTestBit掩码设置为bodyB的类别,以便注册2之间的所有联系人。

我觉得这个function很有用,可以检查你场景中的碰撞和联系。

  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()设置物理之后调用它,它将列出哪些物体发生碰撞,以及哪些联系人将被通知。