SpriteKit:检测完整的节点重叠 [英] SpriteKit: detect complete node overlap

查看:130
本文介绍了SpriteKit:检测完整的节点重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个SKShapeNodes - 一个带有基于边缘的SKPhysicsBody,一个基于音量 - 我想要检测它们的交叉点而不会发生碰撞。我有这个工作正常,SKPhysicsContactDelegate联系方法被调用,因为一个传递到另一个,但我的问题是,当边缘时, didEndContact 被调用不再相交,即使一个物体完全包含在另一个物体内。确定真实接触或重叠的最佳方法是什么,而不仅仅是边缘交叉?我试过 usesPreciseCollisionDetection ,但无济于事。

I have two SKShapeNodes – one with an edge-based SKPhysicsBody, one volume-based – and I want to detect their intersection without collision. I've got this working fine, with the SKPhysicsContactDelegate contact methods getting called as one passes over another, but my issue is that didEndContact gets called when the edges no longer intersect, even when one body is completely contained within the other. What's the best way to determine true contact or overlap, not just edge intersection? I've tried usesPreciseCollisionDetection, to no avail.

推荐答案

As < a href =https://stackoverflow.com/users/2494064/meisenman> meisenman 建议,看起来最好的方法是使用 containsPoint 方法来确定真正的节点重叠。文档声明这个返回一个布尔值,指示一个点是否位于节点的边界框内,但在我的实验中,它看起来像是适用于基于凹边的形状。

As meisenman suggested, it looks like the best way to do this is using the containsPoint method to determine true node overlap. The docs state that this "returns a Boolean value that indicates whether a point lies inside the node's bounding box", but in my experimentation it looks like this works for concave edge-based shapes as well.

因此,如果我想检测两个对象何时不再重叠,那么在 didEndContact中执行 containsPoint 检查是有意义的code> - 但结果是 didEndContact 在每个边不再相交时被调用,即使相同形状的另一个边仍然与同一个对象相交。例如,通过角落的矩形球将产生两个 didEndContact 事件。因此,有必要保持联系事件的绝对计数(开始和结束之间的差异),并且仅在此计数为零时测试包含。

So if I want to detect when two objects no longer overlap, it makes sense to do a containsPoint check within didEndContact – but it turns out didEndContact gets called when each edge is no longer intersected, even if another edge of the same shape still intersects the same object. For example, a ball exiting a rectangle through its corner will yield two didEndContact events. Therefore, it's necessary to keep an absolute count of contact events (the difference between begin and end), and only test for containment when this count is zero.

我的解决方案,在Swift中:

My solution, in 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
    }
  }
}

这篇关于SpriteKit:检测完整的节点重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆