SpriteKit - 使某些SpriteNodes不会在不禁用其物理主体的情况下发生碰撞

时间:2016-05-30 03:12:26

标签: ios swift sprite-kit

我在屏幕上有4个SpriteNodes,我希望不会互相反弹,而是互相流动,同时保持与某些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发生碰撞,但不能与它们相撞?非常感谢任何帮助!

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

2 个答案:

答案 0 :(得分:3)

您需要在physicsBodies上指定collisionBitMask以及category / contact-mask。默认情况下,所有位均为ON。所以像这样:

b.physicsBody?.collisionBitMask = BotCategory | PadCategory

答案 1 :(得分:2)

您在碰撞联系人之间混淆了。碰撞是指2个物理体撞击并相互反弹。碰撞完全由游戏引擎处理。您只需设置必要的physicsWorld.contactDelegate

即可

联系人是指sprite-kit游戏引擎告诉您2个物理机构已经联系的代码。然后,您可以进行一次爆炸,更新分数等.2个实体可能会在未通知联系人的情况下发生碰撞,或者他们可以在没有碰撞的情况下进行联系。您必须设置contactTestBitMask,将您的程序设置为didBeginContact并实施didEndContact / collisionBitMask函数中的任何一个或两个。

2个物体是否发生碰撞是由UInt32.Max控制的。默认情况下,它设置为contactTestBitMask,即一切都与所有内容发生冲突。给定2个身体A和B,身体A可能与身体B碰撞,即从身体B反弹,但身体B NOT 与身体A碰撞,即不受身体A的影响碰撞。

您的代码是否被通知有关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)")} } } } 控制。默认设置为0,即没有注册联系人。给定2个主体A和B,您只需要将主体A的contactTestBit掩码设置为bodyB的类别,即要注册的2之间的所有联系人。

我发现此功能对于检查场景中的碰撞和联系人非常有用:

checkPhysics()

在使用// global variables protected static Entry entry; protected static int index; protected static Highlight highlight; // function where the listener is defined protected void manipulateChart(){ final BarChart mChart = (BarChart) findViewById(R.id.your_chart); // listener mChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() { @Override public void onValueSelected(Entry e, int dataSetIndex, Highlight h) { // set global variables entry = e; index = dataSetIndex; highlight = h; // ... your code ... } } @Override public void onNothingSelected() { onValueSelected(entry, index, highlight); } }); mChart.highlightValues(null); } 设置物理后,只需调用它,它将列出哪些实体发生碰撞以及您将收到通知的联系方式。