Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
290 views
in Technique[技术] by (71.8m points)

ios - didBeginContact is being called multiple times for the same SKPhysicsBody

 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)
    }
}

One physics body is from a texture shield.physicsBody = SKPhysicsBody(texture: shieldTexture, size: shieldTexture.size())

the other is from a circle sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.size.width/2)

When the tow objects contact each other sometimes sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.size.width/2) gets called multiple times. How do i get it to only get called once for each object even though i remove it from the parent as soon as it contacts.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have figured out how to get func didBeginContact(contact: SKPhysicsContact) to only be called once. This allows physics bodies with a texture SKPhysicsBody(texture: size:) to count collisions once even though in reality (because of the nature of the texture's physics body) this function will be called multiple times.

Step 1:

Create a name property for the SKSpriteNode (we will use ball for this example) and set it equal to a unique name. We can do this by creating a int

var number = 0 

ball.name = "ball (number)"

This allows for a unique name evertime that object is created.

Step 2:

Create a array to hold these , append the ball to the array, increment the number

    var array: [String] = []
    var number = 0 

ball.name = "ball (number)" 
array.append(ball.name!)
number ++

Step 3: Now in the func didBeginContact(contact: SKPhysicsContact) find out if the name is in the array. If it is increment the score, remove the node, and remove the name from the array. If the name is not in the array don't do anything.

Removing the name from the array allows us now to only count the function call once.

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!)
        }
    } 
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...