3

我有两个 SKShapeNode——一个带有基于边缘的 SKPhysicsBody,一个基于体积——我想检测它们的交叉点而不会发生碰撞。我的工作正常,当一个人越过另一个人时调用 SKPhysicsContactDelegate 接触方法,但我的问题是当边缘不再相交didEndContact时被调用,即使一个身体完全包含在另一个身体中。确定真正接触或重叠的最佳方法是什么,而不仅仅是边缘相交?我试过了,没有用。usesPreciseCollisionDetection

4

3 回答 3

7
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 上,所以您可能需要稍微使用一下语法。希望这会让您朝着正确的方向前进。

于 2014-06-25T15:38:26.927 回答
4

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

因此,如果我想检测两个对象何时不再重叠,那么在内部进行containsPoint检查是有意义的didEndContact——但事实证明,didEndContact当每个边缘不再相交时会调用它,即使相同形状的另一条边缘仍然与同一个对象相交。例如,一个球通过它的角离开一个矩形将产生两个 didEndContact事件。因此,有必要保持接触事件的绝对计数(开始和结束之间的差异),并且仅在该计数为零时测试遏制。

我的解决方案,在 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
    }
  }
}
于 2014-07-01T04:47:48.277 回答
0

这些是我对 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 语句将不成立。这尚未通过设置节点的主体定义(掩码)进行测试。

我喜欢的是能够在不同的函数或覆盖函数中使用这个 if 语句,这不仅限于“确实开始”或“触摸移动”。
两个 CGPoint 相互之间的图像示例,可能存在限制。

于 2016-11-04T04:56:58.517 回答