views:

1234

answers:

1

I have a countdown timer in my game and I'm trying to figure out how to make it so that it shows two decimal places and records with 2 decimal places in my table. Right now it counts down as a whole number and records as a whole number. Any ideas?

-(void)updateTimerLabel{

     if(appDelegate.gameStateRunning == YES){

                            if(gameVarLevel==1){
       timeSeconds = 100;
       AllowResetTimer = NO;
       }
    timeSeconds--;
    timerLabel.text=[NSString stringWithFormat:@"Time: %d", timeSeconds];
}

    countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTimerLabel) userInfo:nil repeats:YES];
+1  A: 

To have sub-second updates, the timer's interval needs to be < 1. But the precision of NSTimer is just around 50 ms, so scheduledTimerWithTimeInterval:0.01 will not work.

Moreover, the timer can be delayed by various activities, so using timeSeconds will lead to inaccurate timing. The usual way is compare the NSDate now with the date when the timer starts. However, as this code is for a game, the current approach may cause less frustration to players esp. if the program or background processes consumes lots of resources.


The first thing to do is to convert the countdownTimer to sub-second interval.

countdownTimer = [NSTimer scheduledTimerWithTimeInterval:0.67 target:self selector:@selector(updateTimerLabel) userInfo:nil repeats:YES];

Then, don't count down the time by seconds, but centiseconds:

if(appDelegate.gameStateRunning == YES){
   if(gameVarLevel==1){
      timeCentiseconds = 10000;
      AllowResetTimer = NO;
   }
}
timeCentiseconds -= 67;

Finally, divide by 100 in the output:

timerLabel.text=[NSString stringWithFormat:@"Time: %d.%02d", timeCentiseconds/100, timeCentiseconds%100];

Alternatively, use a double:

double timeSeconds;
...
if(appDelegate.gameStateRunning == YES){
   if(gameVarLevel==1){
      timeSeconds = 100;
      AllowResetTimer = NO;
   }
}
timeSeconds -= 0.67;
timerLabel.text=[NSString stringWithFormat:@"Time: %.2g", timeSeconds];
KennyTM
what's an accept rate?
NextRev
Nevermind, i'm new at this, i got it now
NextRev
this didn't give me 2 decimal points...
NextRev
@NextRev: Like how?
KennyTM
I want the countdown to have two decimal places...and count down like 119.99, 119.98, 119.97...
NextRev
@NextRev: To switch from 119.99 to 119.98 does it take 1 second or 0.01 seconds?
KennyTM
.01 but it doesn't work if i set it to .01
NextRev
timerLabel.text = [NSString stringWithFormat:@"Time: %02d", timeSeconds]; doesn't give me any decimal points
NextRev
@NextRev: OK, see update.
KennyTM
i got it working thanks. do you know how i have it show up as a decimal in my sqlite table? it's still showing up as a whole number.
NextRev
@NextRev: You can store as a `double`, but I'd say *don't care*. The users will be unlikely to reach the SQLite table and complain you're using an integer instead of floating point numbers.
KennyTM
actually a mode in my game is timed so hundredths of a second could matter
NextRev
@NextRev: No, I mean by switching to `timeCentiseconds` each unit already corresponds to 0.01 seconds. e.g. the whole number 19998 means 199.98 seconds in the UI.
KennyTM
oh ok, but what field type do i use so that it shows up with a decimal in my high scores menu?
NextRev
@NextRev: You need to format the integer 19999 into 199.99 every time you need to display the number. Also, if you don't mind precision lost, you can use a `double` for the `timeSeconds`, and use `timeSeconds -= 0.67;` in the count-down. (See update.)
KennyTM
it's only showing a .0 in the sqlite table. if the end result was 78.21 it's only showing 78.0
NextRev
@NextRev: How do you insert the result to the SQLite table?
KennyTM
else if(easymediumhard == 2){ sql=[NSString stringWithFormat:@"insert into tblHard(Score) values (?)"];
NextRev
I think i got it, Thank you so much for all your help!!!
NextRev