Swift: score increases twice because collision is detected twice?

467 views Asked by At

I'm building a sprite kit game in swift and I need the score to increase by 1 when collision between 2 nodes is detected. The score is stored in a variable named animalsCount and is outputted to a label node:

    //Score count in stats bar
    //Animal score count

    animalsCount = 0

    animalsCountLabel.text = "\(animalsCount)"
    animalsCountLabel.fontSize = 45
    animalsCountLabel.fontColor = SKColor.blackColor()
    animalsCountLabel.position = CGPoint (x: 630, y: 40)

    addChild(animalsCountLabel)

The two sprite nodes that are colliding are savior and chicken1. Right now, I am keeping score and detecting collision using the following code:

 func didBeginContact(contact: SKPhysicsContact) {

        //Chicken1

        if (contact.bodyA.categoryBitMask == ColliderType.Savior.rawValue && contact.bodyB.categoryBitMask == ColliderType.Chicken1.rawValue )  {

            println("chicken1 contact made")
            chicken1.hidden = true
            chicken1.setScale(0)

            animalsCount++
            animalsCountLabel.text = "\(animalsCount)"


        } else if (contact.bodyA.categoryBitMask == ColliderType.Chicken1.rawValue && contact.bodyB.categoryBitMask == ColliderType.Savior.rawValue)  {

            println("chicken1 contact made")
            chicken1.hidden = true
            chicken1.setScale(0)

        }

Score is not increased in the else if statement because it can't happen in my game.

The problem is that animalsCount increases by 2, not 1, every time savior and chicken1 collide.

After some troubleshooting, I found out this is NOT because the score is being increased for both of the colliding bodies. This is not the case because only 1 line of code is ever satisfied. This is the only line that is satisfied:

if (contact.bodyA.categoryBitMask == ColliderType.Savior.rawValue)

The score goes up by 2 instead of 1 because savior seems to "bounce" off of chicken1 so that contact.bodyA.categoryBitMask is set equal to ColliderType.Savior.rawValue TWICE every time collision appears to occur ONCE.

I don't know how to fix this problem. How do I make it so that collision is only detected ONCE and so the score is only increased once?

1

There are 1 answers

0
blue On

I eventually solved the problem using an Int variable that controlled if statements so collision could only be detected once until the sprite node cycled through and the variable was reset.

I declared a variable called chickenHasBeenGrabbed and set it at 0 initially. Once collision had been detected that first time, I set chickenHasBeenGrabbed to 1. Only after chickenHasBeenGrabbed was set back to 0 could collision be detected again:

func didBeginContact(contact: SKPhysicsContact) {

        //Chicken1

        if chickenHasBeenGrabbed == 0  {

        if (contact.bodyA.categoryBitMask == ColliderType.Savior.rawValue && contact.bodyB.categoryBitMask == ColliderType.Chicken1.rawValue )  {

            println("chicken1 contact made")
            chicken1.hidden = true
            chicken1.setScale(0)

            animalsCount += 1
            animalsCountLabel.text = "\(animalsCount)"

            chickenHasBeenGrabbed = 1


        } else if (contact.bodyA.categoryBitMask == ColliderType.Chicken1.rawValue && contact.bodyB.categoryBitMask == ColliderType.Savior.rawValue)  {

            println("chicken1 contact made")
            chicken1.hidden = true
            chicken1.setScale(0)

        }
        }

        else if chickenHasBeenGrabbed == 1 {

            if (contact.bodyA.categoryBitMask == ColliderType.Savior.rawValue && contact.bodyB.categoryBitMask == ColliderType.Chicken1.rawValue )  {

                println("nothing to do; chicken was already grabbed!")


            } else if (contact.bodyA.categoryBitMask == ColliderType.Chicken1.rawValue && contact.bodyB.categoryBitMask == ColliderType.Savior.rawValue)  {

                println("nothing to do; chicken was already grabbed!")

            }}