Reputation: 2524
I am working on a sprite kit game for the iPhone were there is a player, and 12 "enemies". Each of these enemies is created the same way. I did this with a for loop in the initWithSize method.
for (int i = 1; i <= 12; i++)
{
[self spawnChargesWithNumber:i];
}
The actual method that makes the enemies (spawnChargesWithNumber) is as follows.
- (void)spawnChargesWithNumber:(NSInteger)number
{
self.chargedBall = [[ChargedBall alloc] initWithImageNamed:[NSString stringWithFormat:@"ChargedBall%li", (long)number]];
int minX = self.chargedBall.size.width / 2;
int maxX = self.frame.size.width - self.chargedBall.size.width/2;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX) + minX;
self.chargedBall.position = CGPointMake(actualX, 568);
self.chargedBall.name = [NSString stringWithFormat:@"chargeNumber%li", (long)number];
self.chargedBall.zPosition = 15;
self.chargedBall.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:13.0f];
self.chargedBall.physicsBody.dynamic = YES;
self.chargedBall.physicsBody.affectedByGravity = NO;
self.chargedBall.physicsBody.mass = 0.1;
[self.map addChild:self.chargedBall];
}
This does actually create 12 different enemies, but only the last one is actually a chargedBall object. I have an object called ChargedBall where there is a .h and .m file. In the .m file I have a method to update where the object is.
In the update:currentTime method I call this method to update where the ball is, and I check for collisions with the tileMap in this method as well.
-(void)update:(CFTimeInterval)currentTime
{
NSTimeInterval delta = currentTime - self.previousUpdateTime;
if (delta > 0.02)
{
delta = 0.02;
}
self.previousUpdateTime = currentTime;
[self.player update:delta];
[self.chargedBall update:delta];
[self checkForAndResolveCollisionsForPlayer:self.player forLayer:self.walls];
[self checkForAndResolveCollisionsForCharge:self.chargedBall forLayer:self.walls];
[self processUserMotionForUpdate:currentTime];
[self setViewPointCenter:self.player.position];
}
This works very well if I only have one enemy/chargedBall. If I have multiple chargedBalls then only the last one behave the way it should. The others just stay on the screen. I think this has to do with how I make the chargedBall. I recreate the chargedBall object each time, so that only the last one is actually a chargedBall, not the others because I overwrite them. So my ultimate question is, how can I have all enemies/chargedBall object behave the same way and follow the same method to update themselves? Thanks so much for any and all your help
Upvotes: 1
Views: 653
Reputation: 40030
Store all your ChargedBall
objects in an array. Declare a property:
@property (nonatomic, strong) NSMutableArray *enemies.
Every time you create an enemy, add it to the enemies
array.
- (void)spawnChargesWithNumber:(NSInteger)number
{
ChargedBall *enemy = [[ChargedBall alloc] ...];
// Your code ...
if (!_enemies)
{
_enemies = [[NSMutableArray alloc] init];
}
[_enemies addObject:enemy];
}
Then for each ChargedBall
in array update it in update
method:
for(ChargedBall *enemy in self.enemies)
{
[self checkForAndResolveCollisionsForCharge:enemy forLayer:self.walls];
}
Side note:
This does not apply to this question but it's nice to know.
If you wanted to call a method of each enemy, you could do it in one line using NSArray
's makeObjectsPerformSelector:
method. Example:
[_enemies makeObjectsPerformSelector:@selector(selfDestruct)];
Upvotes: 3
Reputation: 3077
You have a property defined for your chargedBall, however you need a mutable array. Define a property to house all of the balls. Something like this:
@property (nonatomic, strong) NSMutableArray *chargedBalls.
Then change your for loop to this (make sure you've initialized the array somewhere):
- (void)spawnChargesWithNumber:(NSInteger)number
{
ChargedBall *chargedBall = [[ChargedBall alloc] initWithImageNamed:[NSString stringWithFormat:@"ChargedBall%li", (long)number]];
int minX = chargedBall.size.width / 2;
int maxX = self.frame.size.width - chargedBall.size.width/2;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX) + minX;
chargedBall.position = CGPointMake(actualX, 568);
chargedBall.name = [NSString stringWithFormat:@"chargeNumber%li", (long)number];
chargedBall.zPosition = 15;
chargedBall.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:13.0f];
chargedBall.physicsBody.dynamic = YES;
chargedBall.physicsBody.affectedByGravity = NO;
chargedBall.physicsBody.mass = 0.1;
[self.map addChild:chargedBall];
[self.chargedBalls addObject:chargedBall];
}
Then you can iterate the array and determine if there is a collision with any of the balls. However if you're using SpriteKit's physics engine you can have the engine itself notify you of collisions.
Upvotes: 1