I have a game where is uses a countdown timer and when the timer is up, you are brougt to a Game over view. I want to add a feature were if they tap a button, it will add like 1, 2 or 3 more seconds to the timer. I already have the code for the timer (Below), but i just need to know how to add more time to the counter. I thought of it and i have to say when the views will switch and it would need to take into a count the added time.
Code:
-(IBAction)Ready:(id)sender {
[self performSelector:@selector(TimerDelay) withObject:nil afterDelay:1.0];
[self performSelector:@selector(delay) withObject:nil afterDelay:36.5];
}
-(void)TimerDelay {
MainInt = 36;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(countDownDuration)
userInfo:nil
repeats:YES];
if (timer == 0)
{
[timer invalidate];
}
}
-(void)countDownDuration {
MainInt -= 1;
seconds.text = [NSString stringWithFormat:@"%i", MainInt];
}
-(void)delay {
GameOverView1_4inch *second= [self.storyboard instantiateViewControllerWithIdentifier:@"GameOverView1"];
second.finalScore = self.currentScore;
[self presentViewController:second animated:YES completion:nil];
}
If you're using a timer to manage the game, using a perform selector at the same time (to end the game or anything else) kind of defeats the point and makes the management very complex. Choose one route and stick with it.
When the timer is running, you can change it's fire date using setFireDate:
. So, you could get the current fire date, add your time to it and then set the new fire date:
- (void)extendByTime:(NSInteger)seconds
{
NSDate *newFireDate = [[self.timer fireDate] dateByAddingTimeInterval:seconds];
[self.timer setFireDate:newFireDate];
}
Then, your button callbacks are something like:
- (void)buttonOnePressed:(id)sender
{
[self extendByTime:1];
}
- (void)buttonFivePressed:(id)sender
{
[self extendByTime:5];
}
Once you've removed the performSelector
which calls delay
your game end will be defined by
MainInt
reaching zero.
As an aside, don't do this:
if (timer == 0)
The correct approach is:
if (timer == nil)
And if the timer is nil, there's no point in trying to invalidate it...
Also a good idea to take a look at the Objective-C naming guidelines.
Based on your recent comment, it seems that you actually want the timer to continue counting at a second interval, but to add time only to the number of seconds remaining. That's even easier and doesn't require any change to the timer fire date.
- (void)extendByTime:(NSInteger)seconds {
MainInt += seconds;
seconds.text = [NSString stringWithFormat:@"%i", MainInt];
}
And you need to add a check in 'countDownDuration':
if (MainInt <= 0) {
[timer invalidate];
[self delay];
}
To determine when you're done.
You can keep reference of the time you start the timer. Then, when you want to add extra time, calculate how much time has passed since the timer started, invalidate the timer and create a new one passing as time interval the difference between the time left of the previous timer and the extra seconds.
Hy, try to use this:
Put this in -(void)viewDidLoad method
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self
selector:@selector(countDownTimer) userInfo:nil repeats:YES];
then create the -(void)countDownTimer method
- (void)countDownTimer {
// my method which returns the differences between two dates in my case
double diff = [self getDateDifference];
double days = trunc(diff / (60 * 60 * 24));
double seconds = fmod(diff, 60.0);
double minutes = fmod(trunc(diff / 60.0), 60.0);
double hours = fmodf(trunc(diff / 3600.0), 24);
if(diff > 0) {
NSString *countDownString = [NSString stringWithFormat:@"%02.0f day(s)\n%02.0f:%02.0f:%02.0f",
days, hours, minutes, seconds];
// IBOutlet label, added in .h
self.labelCountDown.text= countDownString;
} else {
// stoping the timer
[timer invalidate];
timer = nil;
// do something after countdown ...
}
}
and you can add a - (double)getDateDifference method which returns the difference between two dates in my case
- (double)getDateDifference {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSDate *dateFromString = [[NSDate alloc] init];
NSDate *now = [NSDate date];
NSString *myDateString = @"2013-10-10 10:10:10"; // my initial date with time
// if you want to use only time, than delete the
// date in myDateString and setDateFormat:@"HH:mm:ss"
// this line is not required, I used it, because I need GMT+2
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:+2]];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
// get the date
dateFromString = [dateFormatter dateFromString:myDateString];
// this line is also not required, I used it because I need GMT+2
// so I added two hours in seconds to 'now'
now = [now dateByAddingTimeInterval:60*60*2];
// getting the difference
double diff = [dateFromString timeIntervalSinceDate:now];
NSLog(@"dateString: %@", dateString);
NSLog(@"now: %@", now);
NSLog(@"targetDate: %@", dateFromString);
NSLog(@"diff: %f", diff);
return diff;
}
the output is similar to this
dateString: 2013-10-10 00:20:00
now: 2013-10-10 00:20:00 +0000
target: 2013-10-10 00:20:28 +0000
diff: 28.382786
I hope it was helpfull
Here's a library that you can use.
https://github.com/akmarinov/AMClock