Sprite kit SKPHYSICCONTACT当对象与多个对象碰撞时,首先处理,忽略所有其他。。怎样?

Sprite kit SKPHYSICCONTACT当对象与多个对象碰撞时,首先处理,忽略所有其他。。怎样?,sprite-kit,skspritenode,skphysicsbody,Sprite Kit,Skspritenode,Skphysicsbody,好的,我有一些物理对象,它们都被很好地分类了,我的didBeginContact被正确地激发了,并且做了它应该做的事情。问题是: 我有两类物体,比如球和桨。。。。当球碰到桨时,球会爆炸。。。很简单。。问题在于球可能同时碰到两个桨。。。因此,不止一个didBeginContact被调用,因此发生了不止一次的爆炸(球接触到的每个桨叶1次)。。因此,我试图解决的问题是,如果代码已经处理了涉及原始球的碰撞,我如何从处理中移除/忽略所有与划桨的后续接触?在开始爆炸之前从父级移除SKSpriteNode不会

好的,我有一些物理对象,它们都被很好地分类了,我的didBeginContact被正确地激发了,并且做了它应该做的事情。问题是:

我有两类物体,比如球和桨。。。。当球碰到桨时,球会爆炸。。。很简单。。问题在于球可能同时碰到两个桨。。。因此,不止一个didBeginContact被调用,因此发生了不止一次的爆炸(球接触到的每个桨叶1次)。。因此,我试图解决的问题是,如果代码已经处理了涉及原始球的碰撞,我如何从处理中移除/忽略所有与划桨的后续接触?在开始爆炸之前从父级移除SKSpriteNode不会使其他触点无效,它们仍然会得到处理。。。那我该怎么说呢。。嘿,物理接触的东西。。。那具尸体已经不在照片里了。。。那就把那些隐形眼镜扔掉,不用担心了


我想我可以在执行爆炸等操作之前,明确检查父级在联系人代码中是否仍有可用的SKSpriteNode,但这充其量看起来很麻烦,尽管我认为它会起作用。。。有没有其他/更好的方法来处理这个问题?我必须相信有。

当您获得接触时,将球节点的
物理体的
联系人位掩码设置为
0
。我假设该节点需要销毁,不需要重新使用

这将防止同一节点出现多个联系人

如果上述方法无效,您可以尝试以下方法:

  • 从联系人代理中的父节点删除节点,然后触发爆炸动画
  • 为球节点创建子类
    SKSpriteNode
    SKPhysicsBody
    ,并为例如
    alreadyTouched
    添加属性。然后,可以在联系人代理中检查和设置属性

  • 如果您有三个物理实体(
    ball
    paile1
    paile2
    ),并且
    ball
    设置为与桨叶碰撞(但桨叶不会相互碰撞),并且在同一更新周期内,球与两个桨叶碰撞,然后,游戏引擎将生成两个独立的
    skphysiccontact
    对象-
    ball
    &
    paile1
    ball
    &
    paile2

    didBegincontact
    (Swift2)或
    didbegen(contact:)
    (swift3)(dBC为简洁起见)将在同一
    update()
    周期内调用两次,即在调用
    update()之间将有两次调用dBC
    -首先用于
    球与
    桨1之间的
    skphysiccontact
    ,然后用于
    球与
    桨2之间的接触。您可以在第一次接触期间执行
    ball.removeFromParent()
    ,球将从节点树中删除,但这不会阻止为
    ball
    &
    paile2
    碰撞调用dBC,您可能会对
    ball
    执行相同的操作(爆炸、移除分数等)

    最简单的方法是为球创建一个子类
    SKSPriteNode
    ballNode
    ?),并添加一个属性
    isActive
    ,初始化为
    true
    。这很容易

    在dBC中,当球碰到球拍时,检查其
    isActive
    属性,如果
    false
    ,只需
    返回即可。如果为
    true
    ,则执行正常碰撞操作,然后将
    ball.isActive
    设置为false。第二次调用
    dBC
    时,对
    isActive的检查将防止任何重复操作

    您还可以使用ball的
    userData
    (属于
    SKSpriteNode
    的一部分)来存储
    isActive
    值,以防止子类化,如果您愿意的话


    有其他方法来处理这个问题,但到目前为止,我发现这个方法是有效的,而且是最简单的。

    如果你愿意,你可以使用一个标志,并在身体第一次碰撞时设置它,然后根据该设置标志执行一个动作,然后重置它,这只是一种方法。是的,在didSimulatePhysics或Update中重置标志虽然这可能会节省一些处理时间周期,但实际上与碰撞中的情况没有什么不同,只是检查精灵节点是否仍在父节点中。。。不过,感谢您的建议。如果不起作用,将contactTestBitMask设置为0仍然会导致多个冲突…同样,这可能会安全一些周期,但它与从父级删除没有什么不同,然后在后续调用中查看其是否仍在父级中。我希望有一种东西能直接与物理引擎通信,告诉它物体已经不见了,并扔掉所有与之相关的未决动作,但它似乎并不存在。谢谢。更改contactTestbitMask不起作用,因为联系人已经发生,SK已经创建了SKPhysicContact对象,并将为此调用didBeginContact。刚刚看到这有多旧-抱歉@SteveIves感谢您添加一个新的答案,使此线程保持最新。