SpriteKit:检测完整的节点重叠

我有两个SKShapeNodes – 一个是基于边缘的SKPhysicsBody,一个是基于音量的 – 我想在没有碰撞的情况下检测它们的交集。 我已经得到了这个工作正常,SKPhysicsContactDelegate联系方法被调用时,通过另一个传递,但我的问题是,当不再相交,即使当一个主体完全被包含在另一个时,被调用。 确定真正的接触或重叠的最佳方式是什么,而不仅仅是边缘相交? 我试过用usesPreciseCollisionDetection ,无济于事。

 CGPoint locObj1 = [sprite1 locationInNode:self]; CGPoint locObj2 = [sprite2 locationInNode:self]; if([sprite1 containsPoint: locObj2]) return; if([sprite2 containsPoint: locObj1]) return; 

将此添加到didBeginContact和didEndContact的开头。 这将检查是否有一个节点包含其他节点。 如果是这样,它什么都不做,这将减轻你的问题didBeginContact和didEndContact通常被称为。 我不在我的Mac上,所以你可能需要玩一些语法。 希望这可以让你朝正确的方向发展。

正如meisenman build议的 ,看起来最好的方法是使用containsPoint方法来确定真正的节点重叠。 文档声明这个“返回一个布尔值,表明一个点是否在节点的边界框内”,但在我的实验中,它看起来像这样也适用于基于凹边的形状。

因此,如果我想检测两个对象不再重叠,则在didEndContact执行containsPoint检查是didEndContact – 但是,当每个边不再相交时调用didEndContact ,即使同一形状的另一个边仍然与同一个对象。 例如,一个矩形通过其angular落的球会产生两个 didEndContact事件。 因此,有必要保持接触事件的绝对数量(开始和结束之间的差异),并且只有当这个计数为零时才testing遏制。

我的解决scheme,在Swift中:

 var _contactCount = 0 func didBeginContact(contact: SKPhysicsContact!) { if ((contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask) == (CATEGORY_ONE | CATEGORY_TWO)) { if (_contactCount == 0) { // Contact is actually beginning } _contactCount += 1 } } func didEndContact(contact: SKPhysicsContact!) { if ((contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask) == (CATEGORY_ONE | CATEGORY_TWO)) { _contactCount -= 1 let overlap = contact.bodyA.node.containsPoint(contact.bodyB.node.position) || contact.bodyB.node.containsPoint(contact.bodyA.node.position) if (!overlap && _contactCount == 0) { // Contact is actually ending } } } 

这些是关于swift 3的#meisenman示例的思考。假设我们不想通过掩码进行碰撞检测,而是想知道节点是否在节点内部。 用#meisenman,每个节点的位置正在被使用。

图像两个不同节点的CGPoint示例。

这下面的图像是我们实际上我想要做的。

两个CGPoint的图像示例在另一个中。

#meisenman使用的代码不需要SKPhysics。 这里是Swift 3.0中的代码

 let Object_1: CGPoint! = Sprite_Object_1.position //this obtains the location of the sprite node, through CGPoint. if Object_Sprite_2.contains(Object_1){ print("Then it is true, object 2 is within the location of object 1") } 

我发现的唯一限制是,如果这些节点的中心不在所需节点的主体内,那么这个if语句就不会成立。 这没有通过设置节点的身体定义(掩码)进行testing。

我喜欢的是,有能力使用这个if语句,在不同的function或者function上,这并不仅限于“开始”或“触动”。
两个CGPoint的图像示例在可能的限制之内。