Reputation:
I'm creating a shield power up for my game. The way it works is if you shoot a power up icon, you gain a shield that expires over time. When a rock hits the shield it gets destroyed creating debris. The problem that occurs is that over the course of the game when you hit multiple shield icons, the amount of debris that is created is increased significantly. It's as if there are multiple shields when there is only one. How do I fix this?
My Code:
- (void) didBeginContact:(SKPhysicsContact *)contact{
...
else if (firstBody.categoryBitMask == CollisionCategoryRocks && secondBody.categoryBitMask == CollisionCategoryShield){
// Rock hits Shield
if (!_shield.hidden){
if (firstBody.categoryBitMask == CollisionCategoryRocks){
SpaceRockNode *spaceRock = (SpaceRockNode *) firstBody.node;
[spaceRock removeFromParent];
[self createDebrisAtPosition:contact.contactPoint];
}
}
}
else if ((firstBody.categoryBitMask == CollisionCategoryLaser || firstBody.categoryBitMask == CollisionCategoryPlasmaShot ||firstBody.categoryBitMask == CollisionCategoryProjectile) && secondBody.categoryBitMask == CollisionCategoryShieldIcon){
// Projectile hits Shield Icon
if (!self.shieldIsActive){
self.shield = [ShieldNode shieldAtPosition:CGPointMake(CGRectGetMidX(self.frame)+4, CGRectGetMidY(self.frame)-210)];
[self addChild:self.shield];
self.shieldIsActive = YES;
SKAction *wait = [SKAction waitForDuration:ShieldTimer];
[self runAction:wait completion:^{
self.shield.hidden = YES;
self.shieldIsActive = NO;
}];
}
}
...
}
Upvotes: 0
Views: 80
Reputation: 1443
Your problem is, 2 collisions are happening when debris flies out like crazy:
X
and Shield 1
X
and Shield 2
This causes didBeginContact:
to be called twice, and so, you have twice as much debris flying out.
One thing I would fix, just to shorten your code a bit, is to change this statement...
SpaceRockNode *spaceRock = (SpaceRockNode *) firstBody.node;
[spaceRock removeFromParent];
into...
[firstBody.node removeFromParent];
If you don't do anything else with that Space Rock
, then there's no reason to make the node into a space rock just to use it as a node.
Next, turn this if
statement...
if (!self.shieldIsActive) {
...
}
into...
if (!self.shieldIsActive && ![self.children containsObject:self.shield]) {
...
}
This modified statement makes sure self.shield
is a member of self.children
before adding self.shield
to self.children
a second time. If there's only one shield, only one bunch of debris will fly out.
If self.shield
is set to nil
(in other words, it hasn't been assigned to yet), the containsObject:
method will evaluate to NO
because self.children
doesn't contain nil
. Xcode will actually break with an exception if you try and add a nil
node. Therefore, if self.shield
is nil
, that expression will always evaluate to NO
.
Upvotes: 1