如何在 SpriteKit 中跟踪接触后的节点移动
Posted
技术标签:
【中文标题】如何在 SpriteKit 中跟踪接触后的节点移动【英文标题】:How to track node movement after contact in SpriteKit 【发布时间】:2015-07-15 04:11:08 【问题描述】:我有一个球节点和一个洞节点。我想检测球何时会落入货舱。
目前我正在使用 didBeginContact,但它只给了我接触开始时两个节点的距离,在这种情况下,球不一定会落入洞中(当两个中心之间的距离
有没有办法在接触发生后跟踪球的位置?
【问题讨论】:
【参考方案1】:您可以添加隐形SKSpriteNodes
并跟踪球何时接触它们。在进入球洞之前,node1
就在球洞的顶部(球必须穿过或接触球洞的区域)然后进入球洞,node2
就在球洞之后(同样,一个区域球进洞后必须穿过——或接触——)。
如果球触及node1
而不是node2
,你知道它几乎要进入球洞,但它没有。如果球接触node2
,您就知道球正试图从底部穿过孔。
【讨论】:
【参考方案2】:我想你可以让一个洞的物理体更小。这样,当发生接触时,您将确定球会落入洞中。看看这张图(第二个例子):
除此之外,作为一个额外的想法,当检测到接触时,您可以让球多移动一点,然后将其缩小以产生坠落的印象。
【讨论】:
【参考方案3】:没有必要测试球和球洞之间的接触,因为它不会告诉你目标是否完成。或者,您可以简单地在didSimulatePhysics
中添加一个检查,以查看球是否足够靠近球洞,然后再开始下落动画序列。例如,
override func didSimulatePhysics()
let dx = ball.position.x - hole.position.x
let dy = ball.position.y - hole.position.y
let distance = sqrt(dx*dx+dy*dy)
if (distance < hole.size.width / 2.0)
// Start falling animation sequence
或者,您可以测试球的移动速度是否足以跳过洞
override func didSimulatePhysics()
let dx = ball.position.x - hole.position.x
let dy = ball.position.y - hole.position.y
let distance = sqrt(dx*dx+dy*dy)
if (distance < hole.size.width / 2.0)
// Check if the ball is moving fast
let vx = ball.physicsBody!.velocity.dx
let vy = ball.physicsBody!.velocity.dy
let speed = sqrt(vx*vx+vy*vy)
if (speed < minSpeedToSkipOverHole)
// Start falling animation sequence
【讨论】:
但是性能呢?我的意思是,您的示例中的这个简单检查不会影响性能,但总的来说(或至少在理论上)不会是一个更好的选择来依赖仅触发一次的接触,当球到达某个位置时,而不是不断检查 didSimulatePhysics 中的某些内容?同样在我的例子中,如果一个洞的物理体足够小,球和洞之间的接触意味着目标已经完成.. @Whirlwind,当我阅读 OP 的问题时,我首先想到的是使用小型物理体。然后我意识到物理身体方法只能支持一种球尺寸。如果有不止一个球尺寸,您需要为每个球尺寸设置一个物理体,以确保球在正确的时间下落(想象图中的球更小或更大)。关于性能,我的猜测是 Sprite Kit 在检查物理体之间的接触时会做类似的事情。 是的,好点。如果球太小,可能就不行了。【参考方案4】:这个问题是这样解决的:我为每个球维护一个所有接触孔的 possible_falling_list 并使用另一个计时器来经常检查球是否落入任何孔中。由于每个球的列表都很小,因此性能不是问题。
【讨论】:
以上是关于如何在 SpriteKit 中跟踪接触后的节点移动的主要内容,如果未能解决你的问题,请参考以下文章
使用 SpriteKit 如何以随机但一致的速度将精灵节点移动到一个点