I don't understand why only the animateDarkAst animation works. The first two timers (the one that operates on processKeys and the one that operates on animateDarkAst) work fine but the other timers don't. It doesn't matter what order I write the timers only those two methods work with their respective timers. For the other 3 animations, nothing appears on the screen because no code is being processed within their methods (animateLightAst, animateSmallAst, animateComet).
// Prepare asteroids.
_asteroiddark = [[NSImageView alloc] init];
[_asteroiddark setImage: [NSImage imageNamed:@"asteroiddark"]];
[_asteroiddark setFrame: theModel.darkAstRect];
_asteroidlight = [[NSImageView alloc] init];
[_asteroidlight setImage: [NSImage imageNamed:@"asteroidwhite"]];
[_asteroidlight setFrame: theModel.lightAstRect];
_asteroidsmall = [[NSImageView alloc] init];
[_asteroidsmall setImage: [NSImage imageNamed:@"asteroidsmall"]];
[_asteroidsmall setFrame: theModel.smallAstRect];
// ... and comets
_comet = [[NSImageView alloc] init];
[_comet setImage:[NSImage imageNamed:@"comet"]];
[_comet setFrame: theModel.cometRect];
// Set up key Processing timer for fluid spaceship movement.
timer1 = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(processKeys) userInfo:nil repeats:YES];
// Make a random value for first animation timer.
double randomInterval1 = arc4random() % (4 - 1) + 1;
// Set up key Processing timer for animation.
timer2 = [NSTimer scheduledTimerWithTimeInterval:randomInterval1 target:self selector:@selector(animateDarkAst) userInfo:nil repeats:YES];
double randomInterval2 = ((double)arc4random() / 3) * (3 - 1) + 1;
timer3 = [NSTimer scheduledTimerWithTimeInterval:randomInterval2 target:self selector:@selector(animateSmallAst) userInfo:nil repeats:YES];
double randomInterval3 = ((double)arc4random() / 5) * (5 - 1) + 1;
timer4 = [NSTimer scheduledTimerWithTimeInterval:randomInterval3 target:self selector:@selector(animateLightAst) userInfo:nil repeats:YES];
double randomInterval4 = ((double)arc4random() / 6) * (6 - 1) + 1;
timer5 = [NSTimer scheduledTimerWithTimeInterval:randomInterval4 target:self selector:@selector(animateComet) userInfo:nil repeats:YES];
}
return self;
}
-(void) animateDarkAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroiddark setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroiddark];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroiddark.animator.frame = CGRectOffset(_asteroiddark.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateSmallAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroidsmall setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroidsmall];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroidsmall.animator.frame = CGRectOffset(_asteroidsmall.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateLightAst
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_asteroidlight setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_asteroidlight];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_asteroidlight.animator.frame = CGRectOffset(_asteroidlight.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
-(void) animateComet
{
int randX = arc4random_uniform(self.bounds.size.width);
int randSize = 40 + arc4random() % (120-40+1);
CGPoint startPoint = CGPointMake(randX, self.bounds.size.height);
[_comet setFrame: NSMakeRect(startPoint.x, startPoint.y, randSize, randSize)];
[self addSubview:_comet];
// Create animation (down y-axis)
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setDuration:1.5];
[context setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
_comet.animator.frame = CGRectOffset(_comet.frame, 0, -self.bounds.size.height - 180);
} completionHandler:nil];
}
How should I be handling this? Can I not have 5 timers at once?
The correct Q would be: "Why does at least one timer work?"
As you can see in the documentation the signature of the method has to take one parameter (the instance of NSTimer
that send the message to the delegate).
aSelector The message to send to target when the timer fires.
The selector should have the following signature: timerFireMethod: (including a colon to indicate that the method takes an argument). The timer passes itself as the argument, thus the method would adopt the following pattern:
Change the signature of the methods and of the selector when adding the timer.