Reputation: 19869
I am creating a game. When the user finished the game I am showing him the score. To make it interactive I am counting the score from 0 to the score.
Now since the user can earn 10 points or 100,000 I don't want hime to wait to long so I want that the total time will be fixed no matter what is the score.
So I did that but it seems that the timer interval is not influenced by the interval value.
Where is the problem ?
///score timer
-(void)startScoreCountTimer:(NSNumber*)score{
finishedGameFinalScore = [score integerValue];
CGFloat finishedGameFinalScoreAsFloat = [score floatValue];
CGFloat interval = 2.0f/finishedGameFinalScoreAsFloat;
NSLog(@"interval = %f",interval);
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
timer = [[NSTimer alloc] initWithFireDate:fireDate
interval:interval
target:self
selector:@selector(timerMethod:)
userInfo:nil
repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
}
- (void)timerMethod:(NSTimer*)theTimer{
scoreCount++;
finalScoreLabel.text = [NSString stringWithFormat:@"%i",scoreCount];
if (scoreCount == finishedGameFinalScore ||finishedGameFinalScore ==0) {
[theTimer invalidate];
scoreCount=0;
[self updateMedalsBoard];
}
}
Upvotes: 0
Views: 2713
Reputation: 3558
I would use a repeating NSTimer instead of a runloop.
aTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerMethod:) userInfo:nil repeats:NO];
And change your timerMethod
to something more like the following:
- (void)timerMethod:(NSTimer*)theTimer{
scoreCount = scoreCount + (finishedGameFinalScore * (numberOfSecondsYouWantToRun/100));
finalScoreLabel.text = [NSString stringWithFormat:@"%i",scoreCount];
if (scoreCount == finishedGameFinalScore ||finishedGameFinalScore ==0) {
[theTimer invalidate];
scoreCount=0;
[self updateMedalsBoard];
} else {
theTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timerMethod:) userInfo:nil repeats:NO];
}
}
This will make it so that scoreCount will increment by a non-fixed number, based on their total score. So if you wanted the score counter to run for 2 seconds and your player scored 100, it would incriment by 2 points every tenth of a second. Where if your player scored 100,000 points the score would incriment by 2000 every tenth of a second.
Upvotes: 3
Reputation: 857
NSTimers aren't guaranteed to fire exactly every X seconds (or milliseconds, or in your case, microseconds). You can only know for sure that they'll fire sometime after X seconds (etc.) have passed. In your case, it looks like you're incrementing the score just one point at a time, and that takes up time on the main thread before the NSTimer has an opportunity to fire again, which slows down the whole process.
A better approach might be to simply have the timer repeat every, say, 0.1 seconds for 2 seconds. In each invocation of timerMethod:
, add 1/20th of the total score until you reach the final total in the last iteration. You can, of course play around with the exact intervals to find something that looks good.
Upvotes: 2