Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Kinoko on Wed 28/07/2004 15:34:10

Title: Creating a permanent game timer - SOLVED
Post by: Kinoko on Wed 28/07/2004 15:34:10
I'm trying to make a variable that will show the elapsed playing time in my game. I've made it into a GUI on screen for now just so I can see it's working. It isn't right now, and I'm a bit stumped. I know I'm doing something(s) wrong but I don't know what to change.


if (GetGlobalInt(4)==1) {
Ã,  SetTimer(1, 2400);
Ã,  }

if (IsTimerExpired(1)==1) {
Ã,  second+=1;
Ã,  SetTimer(1, 2400);
Ã,  }

if (second==60) {
Ã,  second=0;
Ã,  minute+=1;
Ã,  }
if (minute==60) {
Ã,  minute=0;
Ã,  hour+=1;
Ã,  }

StrFormat (timehour, "%s", hour);
StrFormat (timeminute, "%s", minute);
StrCopy (time, timehour);
StrCat (time, ":");
StrCat (time, timeminute);

SetLabelText (12, 0, time);


The label itself works, and when the timer is trigger in the game, it goes blank, and a few seconds later, reads as, "(NULL):(NULL)"... so, the format is working but the timer isn't.

I've tried putting the SetLabel line in repeatedly execute and various other things that produce the same result.
Title: Re: Creating a permanent game timer
Post by: Radiant on Wed 28/07/2004 17:01:43
Try %d (for digit) rather than %s (for string) ?
Title: Re: Creating a permanent game timer
Post by: Moox on Wed 28/07/2004 18:00:21
Have you considered the computer clock?
Title: Re: Creating a permanent game timer
Post by: Jet Kobayashi Zala on Wed 28/07/2004 19:13:34
Yeah, using %d should do it. Likewise, you could combine the StrFormat ()'s to make your code a bit smaller:



StrFormat ( time, "%2d:%2d", hour, minute ); // Should give you 00:00 to start with



I'm not sure if the %2d is carried over from C, but if so, that'll save you a bit of code.

Edit:
I tried it out and the %2d doesn't work in AGS, though it might be a good feature to add in at a later version.Ã,  Regardless, that should speed your code up a little bit. As for the timer problem, I'll look into it more and see if I can help.
Title: Re: Creating a permanent game timer
Post by: strazer on Wed 28/07/2004 20:27:57
QuoteI tried it out and the %2d doesn't work in AGS

Quote from: Scorpiorus
DisplaySpeech(JACK, "The new code is %04d", GetGlobalInt(99));
(...) will add leading zeros (up to 4) if necessary.

Try
  StrFormat (time, "%02d:%02d", hour, minute);
Title: Re: Creating a permanent game timer
Post by: Jet Kobayashi Zala on Wed 28/07/2004 20:58:50
Ah, grooviness. Thanks, Strazer! Now to focus on the timing problem. *gets to work testing a few things out for Kinoko*
Title: Re: Creating a permanent game timer
Post by: Kinoko on Thu 29/07/2004 05:03:51
Thanks everyone. That cleans the code up a bit (I thought I had to convert the hour and minute ints into strings for some reason...).

The timer now displays as 00:00 but doesn't go past that.
Title: Re: Creating a permanent game timer
Post by: Gilbert on Thu 29/07/2004 06:41:28
I think the GlobalInt(4) is a bit suspicious, if that part of code you posted was in repeatedly execute and that GlobalInt(4) was indeeed set to 1, the timer will be restarted EVERY gameloop. So, to prevent this, try:

if (GetGlobalInt(4)==1) {
  SetTimer(1, 2400);
  SetGlobalInt(4,0);
  }

Also, try changing all those 2400 to 40. Under normal cases, 40 gameloops make 1 second (unless you changed it), so 2400 gameloops would be 60 seconds already (unless you really need to wait that long for second to advance by 1).
Title: Re: Creating a permanent game timer
Post by: Kweepa on Thu 29/07/2004 07:06:27
You should use GetGameSpeed() instead of 40 to be absolutely sure...
Title: Re: Creating a permanent game timer
Post by: Jet Kobayashi Zala on Thu 29/07/2004 07:14:14
Here's what I ended up with after everyone's suggestion and it worked for me:


in repeatedly_execute:

if ( GetGlobalInt (4) == 1 ) {Ã,  Ã,  Ã,  Ã,  Ã,  // Make sure timer is supposed to be running
Ã,  SetGlobalInt (4, 0);Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, // Disable it so this doesn't keep getting called
Ã,  SetTimer (1, GetGameSpeed());Ã,  // Start the timer based on the game's speed so that time is measured correctly
}

if ( IsTimerExpired(1) ) {Ã,  // Once the timer has expired (one second)
Ã,  second++;Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, // Increment seconds
Ã,  if ( second == 60 ) {Ã,  Ã,  Ã,  // Increment minutes and reset seconds if needed
Ã,  Ã,  second = 0;
Ã,  Ã,  minute++;
Ã,  }
Ã,  if ( minute == 60 ) {Ã,  Ã,  Ã,  // Increment hours and reset minutes if needed
Ã,  Ã,  minute = 0;
Ã,  Ã,  hour++;
Ã,  }
Ã,  SetGlobalInt (4, 1);Ã,  Ã,  Ã,  // Restart the timer
}

StrFormat (time, "%02d:%02d:%02d", hour, minute, second); // Format it!

SetLabelText (STATUSLINE, 0, time); // Print it!


And that worked fine for me Kinoko. Hope that helps you too.
Title: Re: Creating a permanent game timer
Post by: Kinoko on Thu 29/07/2004 07:41:57
Gil: Oops, the 2400 was supposed to calculate a minute, not a second. Again, put tht down to my brain being fried at the time.

Jet: Works beautifully, thanks! ^_^

So the timer works just the way I was after, except that I don't need it printed, I just need the game keeping track of the time variable internally so I'll get rid of that line. A new problem is that the game is keeping track of time constantly and now I can't move my character (keyboard controlled movement based around code contained in repeatedly_execute as well).

Should I put the time code into repeatedly_execute_always or something?
Title: Re: Creating a permanent game timer
Post by: Gilbert on Thu 29/07/2004 07:59:24
Quote from: Kinoko on Thu 29/07/2004 07:41:57
A new problem is that the game is keeping track of time constantly and now I can't move my character (keyboard controlled movement based around code contained in repeatedly_execute as well).
Why not? you can always do more than one thing in a function, eg.

function repeatedly_execute() {
  //stuff1 bla bla bla
  //stuff2 blah bla
}

Quote
Should I put the time code into repeatedly_execute_always or something?
It wouldn't make "much" difference according to how that code was scripted, except that putting it in "always" may make it a bit more accurate (for example, if the timer expires when a blocking script is being executed, second wouldn't advance until the script was finished if you didn't put it in "always").
Title: Re: Creating a permanent game timer
Post by: Kinoko on Thu 29/07/2004 08:07:33
I don't know why it isn't working. Idle animation still works, other key functions that bring up GUIs and so forth still work, but not the character movement. Here's my entire repeatedly_execute script, just in case you can see anything obvious:


#sectionstart repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute()
  {

//////////////////////////////////TIME////////////////
if ( GetGlobalInt (4) == 1 ) {          // Make sure timer is supposed to be running
  SetGlobalInt (4, 0);                     // Disable it so this doesn't keep getting called
  SetTimer (1, GetGameSpeed());  // Start the timer based on the game's speed so that time is measured correctly
}

if ( IsTimerExpired(1) ) {  // Once the timer has expired (one second)
  second++;                     // Increment seconds
  if ( second == 60 ) {      // Increment minutes and reset seconds if needed
    second = 0;
    minute++;
  }
  if ( minute == 60 ) {      // Increment hours and reset minutes if needed
    minute = 0;
    hour++;
  }
  SetGlobalInt (4, 1);      // Restart the timer
}

StrFormat (time, "%02d:%02d:%02d", hour, minute, second); // Format it!

//SetLabelText (12, 0, time); // Print it!

//////////////////////////////////////////////////////

if (IsGamePaused()==0) {
// --- keyboard control ---
int CharId, Direction, dx, dy;
// neue Richtung ermitteln
if ((IsKeyPressed (371) > 0) || (IsKeyPressed (55) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_UP_LEFT;
else if ((IsKeyPressed (373) > 0) || (IsKeyPressed (57) > 0) || ((IsKeyPressed (372) > 0) && (IsKeyPressed (377) > 0))) Direction = DIR_UP_RIGHT;
else if ((IsKeyPressed (379) > 0) || (IsKeyPressed (49) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (375) > 0))) Direction = DIR_DOWN_LEFT;
else if ((IsKeyPressed (381) > 0) || (IsKeyPressed (51) > 0) || ((IsKeyPressed (380) > 0) && (IsKeyPressed (377) > 0))) Direction =DIR_DOWN_RIGHT;
else if ((IsKeyPressed (372) > 0) || (IsKeyPressed (56) > 0)) Direction = DIR_UP;
else if ((IsKeyPressed (375) > 0) || (IsKeyPressed (52) > 0)) Direction = DIR_LEFT;
else if ((IsKeyPressed (376) > 0) || (IsKeyPressed (53) > 0)) Direction = DIR_STOP;
else if ((IsKeyPressed (377) > 0) || (IsKeyPressed (54) > 0)) Direction = DIR_RIGHT;
else if ((IsKeyPressed (380) > 0) || (IsKeyPressed (50) > 0)) Direction = DIR_DOWN;
else Direction = DIR_STOP;

if (IsKeyPressed(65)==1) { //RUNNING - 'A' button held down

   if (isRunning==0) {
      StopMoving(GetPlayerCharacter());
      SetCharacterSpeed(GetPlayerCharacter(), 12);
      isRunning = 1;
      Direction = DIR_STOP;
   }

} else {

   if (isRunning==1) {
      StopMoving(GetPlayerCharacter());
      SetCharacterSpeed(GetPlayerCharacter(), 7);
      isRunning = 0;
      Direction = DIR_STOP;
   }
}

// Vergleich mit aktueller Richtung
if (PrevDirection != Direction)
{
PrevDirection = Direction;
CharId = GetPlayerCharacter ();
if (Direction == DIR_STOP) { StopMoving (CharId); } // 5 Stop (numeric pad)
else
{
if (Direction == DIR_UP_LEFT) { dx = -DIR_DISTANCE; dy = -DIR_DISTANCE; } // 7 Home (numeric pad)
else if (Direction == DIR_UP) { dx = 0; dy = -DIR_DISTANCE; } // 8 Up arrow
else if (Direction == DIR_UP_RIGHT) { dx = DIR_DISTANCE; dy = -DIR_DISTANCE; } // 9 PgUp (numeric pad)
else if (Direction == DIR_LEFT) { dx = -DIR_DISTANCE; dy = 0; } // 4 Left arrow
else if (Direction == DIR_RIGHT) { dx = DIR_DISTANCE; dy = 0; } // 6 Right arrow
else if (Direction == DIR_DOWN_LEFT) { dx = -DIR_DISTANCE; dy = DIR_DISTANCE; } // 1 End (numeric pad)
else if (Direction == DIR_DOWN) { dx = 0; dy = DIR_DISTANCE; } // 2 Down arrow
else if (Direction == DIR_DOWN_RIGHT) { dx = DIR_DISTANCE; dy = DIR_DISTANCE; } // 3 PgDn (numeric pad)
MoveCharacterStraight (CharId, character [CharId].x + dx, character [CharId].y + dy);
}
}
}    
}

#sectionend repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE
Title: Re: Creating a permanent game timer
Post by: Gilbert on Thu 29/07/2004 08:44:08
Strange, works for me.
Title: Re: Creating a permanent game timer
Post by: Kinoko on Thu 29/07/2004 14:50:26
No, you're right, it's fine. Something else was the problem, and it's fixed now.

Anyway, thanks everyone! ^_^
Title: Re: Creating a permanent game timer - SOLVED
Post by: Mel_O_Die on Mon 28/08/2006 21:51:38
i reply here with a new question because i don't want to create a new topic about timers but i have a little problem with that code

it works fine (with some modifications for AGS 2.72 script) but this timer pauses automatically when character's speaking or player browses inventory

how can i do to get this timer works in these cases?

(but i want it paused when the game is "officially" paused like in menu or save/load windows

thanks!

PS: here's my code for 2.72
in top of global script i declare these variables:

// main global script file
int second;
int minute;
int hour;

and in repeatedly execute i have that:

function repeatedly_execute() {
//////////////////////////////////TIME////////////////
if ( GetGlobalInt (4) == 1 ) {Ã,  Ã,  Ã,  Ã,  Ã,  // Make sure timer is supposed to be running
Ã,  SetGlobalInt (4, 0);Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, // Disable it so this doesn't keep getting called
Ã,  SetTimer (1, GetGameSpeed());Ã,  // Start the timer based on the game's speed so that time is measured correctly
}

if ( IsTimerExpired(1) ) {Ã,  // Once the timer has expired (one second)
Ã,  second++;Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, // Increment seconds
Ã,  if ( second == 60 ) {Ã,  Ã,  Ã,  // Increment minutes and reset seconds if needed
Ã,  Ã,  second = 0;
Ã,  Ã,  minute++;
Ã,  }
Ã,  if ( minute == 60 ) {Ã,  Ã,  Ã,  // Increment hours and reset minutes if needed
Ã,  Ã,  minute = 0;
Ã,  Ã,  hour++;
}
Ã,  SetGlobalInt (4, 1);Ã,  Ã,  Ã,  // Restart the timer
Ã, 
}
Ã, 
counter.Text = String.Format("%02d:%02d:%02d", hour, minute, second); // "counter" is my label's name
}
Title: Re: Creating a permanent game timer - SOLVED
Post by: SSH on Mon 28/08/2006 22:28:39
Move the code to repeatedly_execute_always and it will carry on through everything except dialog option chooosing
Title: Re: Creating a permanent game timer - SOLVED
Post by: Mel_O_Die on Mon 28/08/2006 23:08:37
i've tried that but it doesn't works, nothing is written in the label

maybe i must change a thing in the code but i don't know what to do and where
Title: Re: Creating a permanent game timer - SOLVED
Post by: Gilbert on Tue 29/08/2006 02:36:10
That means, your inventory window is a popup modal which will pause the game.
I'm not sure, but I think timer won't decrement when a popup modal GUI's on.

You may either change the invertory GUI to other non-blocking mode, or, don't use the times, use a variable instead:

in top of global script i declare these variables:

// main global script file
int second;
int minute;
int hour;
int timecoutn=1; //set to 1 to guarantee it to work for the first time and the rest

and in repeatedly execute:

function repeatedly_execute() {
//////////////////////////////////TIME////////////////

timecoutn--;
if ( timecoutn==0 ) {Ã,  // Once the timer has expired (one second)
Ã,  second++;Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, // Increment seconds
Ã,  if ( second == 60 ) {Ã,  Ã,  Ã,  // Increment minutes and reset seconds if needed
Ã,  Ã,  second = 0;
Ã,  Ã,  minute++;
Ã,  }
Ã,  if ( minute == 60 ) {Ã,  Ã,  Ã,  // Increment hours and reset minutes if needed
Ã,  Ã,  minute = 0;
Ã,  Ã,  hour++;
}
Ã,  timecoutn=GetGameSpeed();Ã,  Ã,  Ã,  // Restart the timer
Ã, 
}
Ã, 
counter.Text = String.Format("%02d:%02d:%02d", hour, minute, second); // "counter" is my label's name
}


If you don't want the time to count when some certain GUIs are on, just change the timecoutn--; line to something like:

if (!gSave.Visible||!gLoad.Visible) timecoutn--;
Title: Re: Creating a permanent game timer - SOLVED
Post by: Mel_O_Die on Tue 29/08/2006 09:31:58
yeah! it works perfectly  ;D

thanks!