Swift Spritekit 我检测到碰撞,但它读取了多次碰撞

3

AppImage 我有一个由4个不同颜色矩形组成的障碍墙,要穿过这堵墙需要球的颜色与墙上矩形的颜色相匹配。当球穿过障碍墙后,将会出现一堵新的障碍墙。然而,当我检测到这种碰撞时,会得到多个碰撞读数。我通过打印死亡或存活进行了测试,并且它会多次打印两者或更多。

func didBegin(_ contact: SKPhysicsContact) {

    if let nodeA = contact.bodyA.node as? SKShapeNode, let nodeB = contact.bodyB.node as? SKShapeNode {
        if nodeA.fillColor != nodeB.fillColor {
            print("DEAD")
        }
        else {
            print("Alive")
        }
    }
}      

please help!!!


你应该谈论的不是碰撞,而是接触。 - El Tomato
可能是为什么didBeginContact会被多次调用?的重复问题。 - Knight0fDragon
1个回答

3
是的-这种情况确实会发生。处理它的方法(在某些情况下,您无法让Sprite-Kit不调用didBegin多次)是确保您的接触代码适应此,并且多次处理合同不会引起问题(例如多次添加分数,删除多个生命,尝试访问已删除的节点或physicsBody等)。
这里有一个讨论:Sprite-Kit registering multiple collisions for single contact 您可以做的一些事情包括:
  • 如果要删除已联系的节点,请在删除之前检查其是否为nil(用于重复联系)
  • 将节点添加到一个集合中,然后在didFinishUpdate中删除集合中的所有节点
  • 向节点的userData添加“未激活”标志
  • 将节点作为SKSpriteNode的子类并添加一个inactive属性
  • 等等。

@Whirlwind 将节点添加到要在 didFinishUpdate 中删除的集合中,是否解决了多次添加得分或失去多个生命的问题?还是您必须将该逻辑移动到 didFinishUpdate 中? - Steve Ives
嗯,我猜它可以解决这部分问题...你需要检查节点是否不在数组中,以便采取适当的操作(减少/增加生命数量,增加总积分等)。我的意思是你的方法也有效,完全没问题。 - Whirlwind
1
我喜欢使用类别掩码中的第31位来表示正在死亡的物品。 - Knight0fDragon
在你的didBegin方法中,如果第31位被设置了,那么返回,因为这是一个幻影碰撞。 - Knight0fDragon
@SteveIves 是的,比在字典上进行哈希抓取要快得多,简单的位运算(这是伪代码):guard(~(categoryBitMask & (1 << 31))) else return - Knight0fDragon
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接