Hi scripters,
I know there are modules for countdown timers out there, but I wanted to see if I could script my own based on the background speech of an invisible character rather than a GUI. It seemed simpler, but evidently is not.
The problem is this: I can't get the countdown to update - it will display the initial value of the min and sec variables but never change. I've read the "string formatting" and "string.format" sections of the manual several times, and my "repeatedly_execute_always" function is running other things like looping animations perfectly well.
I have tried reordering the lines of code several different ways, and changing the frequency of updates to the timer (for example, updating only every 3 seconds), as well as substituting "if" statements for "while" statements. Nothing changes. I feel like I must be missing something obvious but cannot figure out what it is.
Any help would be hugely appreciated. Relevant code is below (I haven't coded what to do at 0 yet because this problem has gotten in the way):
int min;
int sec;
String TimerText;
function room_Load()
{
min = 2;
sec = 60;
TimerText = String.Format("%d : %d", min, sec);
SetGameSpeed(40); //40 loops = 1 second
SetTimer(1, 2400); //2400 = 40*60 = 60 seconds
SetTimer(2, 40); // 40 = 1 second
}
function repeatedly_execute_always()
{
if (IsTimerExpired(1))
{
min -=1;
SetTimer(1, 2400);
}
if (IsTimerExpired(2))
{
sec -=1;
cTimer.SayBackground(TimerText);
SetTimer(2, 40);
}
}
Well, TimerText never updates, because it's in room_load.
Just put TimerText = String.Format("%d : %d", min, sec); in repeatedly_execute_always() before cTimer.SayBackground(TimerText);
Exactly, an assignment statement like
variable = value;
does not magically extend into the future; when this line is executed, the current value on the right is written into memory and that's it.
If the value changes, you also need to run the statement again or the variable simply keeps its old value.
Matti, thanks very much--I knew it must be something simple like that, and your fix worked perfectly.
And Khris, I appreciate the explanation--it's helpful to understand not just the structure of the code but what's going on "under the hood."
Thank you both for answering! Much gratitude.
Btw, you can slightly improve the code by 1) not using a minute variable 2) not hard-coding 40 FPS
int secs = 180; // 3 minutes
// room_Load
SetTimer(1, GetGameSpeed()); // one second
// rep_ex_always
if (IsTimerExpired(1)) {
secs--;
TimerText = String.Format("%d : %02d", secs / 60, secs % 60); // force two digit seconds
if (secs == 0) { ... }
else SetTimer(1, GetGameSpeed()); // one second
}
Hey Khris, I didn't see this before now. Thanks for the simplified code! It's great to have more experienced people to help make me a better coder. Much appreciated.