Sprite kit SKPHYSICCONTACT当对象与多个对象碰撞时,首先处理,忽略所有其他。。怎样?
好的,我有一些物理对象,它们都被很好地分类了,我的didBeginContact被正确地激发了,并且做了它应该做的事情。问题是: 我有两类物体,比如球和桨。。。。当球碰到桨时,球会爆炸。。。很简单。。问题在于球可能同时碰到两个桨。。。因此,不止一个didBeginContact被调用,因此发生了不止一次的爆炸(球接触到的每个桨叶1次)。。因此,我试图解决的问题是,如果代码已经处理了涉及原始球的碰撞,我如何从处理中移除/忽略所有与划桨的后续接触?在开始爆炸之前从父级移除SKSpriteNode不会使其他触点无效,它们仍然会得到处理。。。那我该怎么说呢。。嘿,物理接触的东西。。。那具尸体已经不在照片里了。。。那就把那些隐形眼镜扔掉,不用担心了Sprite kit SKPHYSICCONTACT当对象与多个对象碰撞时,首先处理,忽略所有其他。。怎样?,sprite-kit,skspritenode,skphysicsbody,Sprite Kit,Skspritenode,Skphysicsbody,好的,我有一些物理对象,它们都被很好地分类了,我的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感谢您添加一个新的答案,使此线程保持最新。