Ios 同一SKPhysicsBody多次调用didBeginContact
一个物理实体来自纹理Ios 同一SKPhysicsBody多次调用didBeginContact,ios,swift,sprite-kit,skphysicsbody,Ios,Swift,Sprite Kit,Skphysicsbody,一个物理实体来自纹理shield.physicsBody=SKPhysicsBody(纹理:shieldTexture,大小:shieldTexture.size()) 另一个来自圆sand.physicsBody=SKPhysicsBody(圆半径:sand.size.width/2) 当两个对象有时相互接触时sand.physicsBody=SKPhysicsBody(圆圈半径:sand.size.width/2) 被多次调用。如何使每个对象只被调用一次,即使我在它接触后立即将其从父对象
shield.physicsBody=SKPhysicsBody(纹理:shieldTexture,大小:shieldTexture.size())
另一个来自圆sand.physicsBody=SKPhysicsBody(圆半径:sand.size.width/2)
当两个对象有时相互接触时sand.physicsBody=SKPhysicsBody(圆圈半径:sand.size.width/2)
被多次调用。如何使每个对象只被调用一次,即使我在它接触后立即将其从父对象中移除。我已经找到了如何使func didBeginContact(contact:skphysiccontact)
只被调用一次的方法。这允许具有纹理SKPhysicsBody(纹理:大小:)
的物理实体计算一次碰撞,即使在现实中(由于纹理的物理实体的性质),此函数将被多次调用
步骤1:
为SKSpriteNode创建一个name属性(本例中我们将使用ball)
并将其设置为唯一名称。我们可以通过创建一个int来实现这一点
func didBeginContact(contact: SKPhysicsContact) {
if ( contact.bodyA.categoryBitMask & BodyType.shield.rawValue ) == BodyType.shield.rawValue {
contact.bodyB.node?.removeFromParent()
counter++
println(counter)
} else if ( contact.bodyB.categoryBitMask & BodyType.shield.rawValue ) == BodyType.shield.rawValue {
contact.bodyA.node?.removeFromParent()
counter++
println(counter)
}
}
这允许每次创建对象时都有一个唯一的名称
步骤2:
创建一个数组来容纳这些球,将球附加到数组中,增加数字
var number = 0
ball.name = "ball \(number)"
步骤3:现在在func didBeginContact(contact:skphysiccontact)
中查找名称是否在数组中。如果是递增分数,则删除节点,并从数组中删除名称。如果名称不在数组中,请不要执行任何操作
从数组中删除名称后,我们现在只需对函数调用计数一次
var array: [String] = []
var number = 0
ball.name = "ball \(number)"
array.append(ball.name!)
number ++
LearnCos2D是正确的,只要两个对象的SKPhysicsbody接触,SKPhysicsbody didBeginContact就会连续调用,因为我们在
SKPhysicsbody(纹理:xxx,大小:xx)
中允许的形状可以有多种形式和形状
对于那些只需要检测一次的人,我们只需要使用布尔值作为标志来检查检测是否完成并结束
我是这样做的:
var
boolean:
func didBeginContact(contact: SKPhysicsContact) {
if ( contact.bodyA.categoryBitMask & BodyType.shield.rawValue ) == BodyType.shield.rawValue {
var name = contact.bodyB.node?.name!
let index = find(array, name!)
if contains(array, name!) {
score++
contact.bodyB.node?.removeFromParent()
array.removeAtIndex(index!)
}
}
}
didMoveToView
下面)
didBeginContact
:
contactDone = false
func didBeginContact(contact:SKPhysicsBody){
if((contact.bodyA.categoryBitMask) == scoreCategory || (contact.bodyB.categoryBitMask) == scoreCategory){
if (contactDone == false){
// Increment score
score++
// Set flag to disable multiple calls by checking in didEndContact
contactDone = true
}
}
}
didEndContact
中再次检查:
contactDone = false
func didBeginContact(contact:SKPhysicsBody){
if((contact.bodyA.categoryBitMask) == scoreCategory || (contact.bodyB.categoryBitMask) == scoreCategory){
if (contactDone == false){
// Increment score
score++
// Set flag to disable multiple calls by checking in didEndContact
contactDone = true
}
}
}
它的工作原理与我使用SKPhysicBody(circleOfRadius:object.size.height/2)时的工作原理一样。在这种情况下,您可以在没有阵列的情况下使其工作。与此相反:
func didEndContact(contact: SKPhysicsContact) {
if((contact.bodyA.categoryBitMask) == scoreCategory || (contact.bodyB.categoryBitMask) == scoreCategory){
if(contactDone == true){
contactDone = false
}
}
}
使用类似以下内容:
contact.bodyA.node?.removeFromParent()
counter++
在第一次联系时,您从父节点删除节点,在随后的调用中,if语句中的代码将被跳过。如果您使用
contactbitmask
确定要捕获哪些冲突,则有一个非常简单的解决方案
只需更新您不想被重复检测到的对象的<代码> CythyByPase<代码>,这样系统就不会考虑后续的函数调用了。p> 使用基于纹理的物理体时,问题似乎更常见。我绕过它的方法是,如果在上一次碰撞触发器中指示相同的“contact.bodyA.node”,则禁止“didbeagin(uu'contact:skphysiccontact)”继续。i、 e:
if let node = contact.bodyA.node as? SKSpriteNode {
if node.parent != nil {
node.removeFromParent()
counter++
}
}
我的解决方案是,通过Date()计算时间。timeIntervalSince1970 联系迪德贝京
if lastNodeA != contact.bodyA.node {
lastNodeA = contact.bodyA.node
...
let passedTime=Date().timeIntervalSince1970-lastContactTime
lastContactTime=Date()。时间间隔1970
如果通过时间<0.01{
//同一物体
返回
}
我相信这是按预期工作的,因为“来自纹理的身体”可能会在内部生成多个形状,每个形状都可能导致接触事件。在物理模拟步骤结束之前,移除节点不会移除实体。您必须手动“标记”已在此接触事件中处理的节点或主体,以便您可以跳过相同主体的任何后续接触事件。我希望有一个选项,用于从纹理设置SKPhysicsBody,使其通过参数进行设置,以便其行为与circleOfRadius中的SKPhysicsBody完全相同,因此在某些情况下,它只计算1次命中/接触比创建任何额外的逻辑(包括下面的答案)更令人渴望。此外,如果不需要更多联系人,也可以节省不检测联系人的资源。您不能将SKSpriteNode添加到阵列中吗?它是通过引用传递的,所以我们可以比较它们,我不明白为什么我们需要指定唯一的名称。当我使用“SKPhysicsBody(纹理:ghostTexture,大小:Obj.size)”时不起作用