Alex
Alex

Reputation: 43

SpriteKit score is acting randomly

I am creating a game with SpriteKit and attempting to increase the score upon a collision. For some odd reason every time the score increase it is by a random number not just 1.

In the didBeginContact method I have a collision between a bullet and an alien. Every time the collide I would like the score to increase the score by 1. Except it has a mind of it's own and will randomly increase it by a number between 1 - 6. I have been through every line of code and have attempted to add scoring into the game multiple times but it just won't increase by 1 as I would like it too. At the moment my code is like this.

In my header file I create a property for the score:

@property (nonatomic) int score;

Then in my main game scene, I add the following

-(void)setScore:(int)score
{
    _score = score;
    _scoreLabel.text = [NSString stringWithFormat:@"%d", score];
}

In my init method I also set the score to start at 0

self.score = 0;

In my new game method I also make sure the score is set back to 0

self.score = 0;

Then my collision detection looks like this. I increment the score with self.score++;

if (firstBody.categoryBitMask == kAlienCategory && secondBody.categoryBitMask == kBulletCategory) {
        //Collision Between Bullet & Alien
        self.score++;
        if (firstBody.node) {
            [self alienExplosion:firstBody.node.position];
            [firstBody.node removeFromParent];
        }
        if (secondBody.node) {
            [self bulletExplosion:secondBody.node.position];
            [secondBody.node removeFromParent];
        }
    }

UPDATE: I added an NSLog to show how the score was updating in the console. And it showed exactly how the score was updating randomly between 1 - 6. The screenshot of the console shows the score updating to 6 where it should only have been 1

enter image description here

enter image description here

Upvotes: 4

Views: 166

Answers (1)

Luca Angeletti
Luca Angeletti

Reputation: 59496

In Box2D (the physics engine that SpriteKit uses internally) a single contact can produce multiple invocations of the related callback function.

So your score value is being incremented several times because your method didBeginContact is called multiple times for the same contact.

You can prevent this behavior in several ways. E.g. if your Alien can be hit by the bullet only once, you can add a BOOL property isAlive to Alien and change your code as follow.

//Collision Between Bullet & Alien
if (firstBody.categoryBitMask == kAlienCategory && secondBody.categoryBitMask == kBulletCategory) {
    Alien * alien = nil;
    if ([firstBody.node isKindOfClass:Alien.class]) {
        alien = (Alien*)firstBody.node 
    } else if ([secondBody.node isKindOfClass:Alien.class]) {
        alien = (Alien*)secondBody.node 
    }

    if (alien && alien.isAlive) {
        alien.isAlive = NO
        self.score++;
        if (firstBody.node) {
            [self alienExplosion:firstBody.node.position];
            [firstBody.node removeFromParent];
        }
        if (secondBody.node) {
            [self bulletExplosion:secondBody.node.position];
            [secondBody.node removeFromParent];
        }
    }
}

Upvotes: 3

Related Questions