Game Development Community

Time in TGB

by Tyler Slabinski · in Torque Game Builder · 03/09/2009 (4:41 pm) · 13 replies

Hey, I just wanted to ask how to program time in a TGB game. I want it to get a random number (1-5) every 256 ms. I do not really understand how ticks work, but I would like it to flash an animation if it returns the value of 1, then disappear once the animation finishes.

EDIT: I would like to tell you I have checked my book, and TDN on how to do this, I do not want to learn from an example script, I want an explanation so I can understand how it works.

#1
03/10/2009 (7:57 am)
Why don't you just use the Schedule command. Make a function to do what you want, then schedule it every 256ms or whatever time you need.
#2
03/10/2009 (11:33 am)
Alright... The first thing you need to do is kick off the timer. It sounds like you want this to happen as soon as the level begins, so you need to find the onLevelLoaded callback. A callback is a function that is automatically called at a predetermined time, in this case when the level finishes loading.

If you didn't want it to start when the level loads, you can kick off your schedule from simply calling your function, in this case 'startAnimationTimer().
function t2dSceneObject::onLevelLoaded(%this, %scenegraph)
{
     //kick off the timer here
     schedule(256, 0, startAnimationTimer);
}

function startAnimationTimer()
{
     //let's get that random number you wanted
     %random = getRandom(1,5);
     
     //if we get that one out of 5, let's play the animation
     if(%random == 1)
     {
          nameOfAnimation.enabled = true;     
          nameOfAnimation.setAnimationFrame(0);
          nameOfAnimation.setVisible(true);
          nameOfAnimation.playAnimation(linkImageAnimationName, false, 0, false);
     }
     else
     {
         //if we don't get that one out of 5, let's wait 256 ms and try again
         schedule(256, 0, startAnimationTimer);
     }
}
Fortunately, there's also a callback when an animation ends. If we call our original function inside there, it will repeat the schedule above and you'll get what you're looking for. How clever. If we don't include this callback, the startAnimationTimer() would only be called once and we need it to loop.
function t2dAnimatedSprite::onAnimationEnd(%this)
{
     //let's clean up that animation
     nameOfAnimation.enabled = false;     
     nameOfAnimation.setAnimationFrame(0);
     nameOfAnimation.setVisible(false);

     //Let's start this thing all over again
     startAnimationTimer();
}
Please note that this isn't tested as I don't have TGB on this computer but it should get you started on your way to learning all about scheduling in TGB.

Best of luck!
`RJ
#3
03/10/2009 (11:58 am)
Ahh, I never knew there was a Schedule function in TGB, thanks for the help! Yet I can't seem to wonder:

%random = getRandom(1,5);

Wouldn't it need to have all the numbers from 1-5?

%random = getRandom(1, 2, 3, 4, 5);

I will try it both ways, and find out which one is correct (might be both), but thanks.
#4
03/10/2009 (12:16 pm)
nope... Check the TGB reference page for stuff like that. It explains that the getRandom function will accept 0, 1 or 2 parameters. In your case you'd want to use as described above. Unless you wanted to start your count at 0, which is good practice since most indices in computer programming begin at 0, then you could use getRandom(4);

http://tdn.garagegames.com/wiki/TorqueScript_Console_Functions_21

#5
03/10/2009 (12:24 pm)
Ahh thanks... That explains so many errors in my game...
#6
03/10/2009 (4:06 pm)
This is odd... Here is my script:

function t2dSceneObject::onLevelLoaded(%this, %scenegraph)
{
     $Lightning = %this;

     //kick off the timer here
     schedule(256, 0, lightningTimer);
}

function lightningTimer()
{
     //let's get that random number you wanted
     %random = getRandom(1,5);
     
     //if we get that one out of 5, let's play the animation
     if(%random == 1)
     {
          //prepare the animation for launch
          $Lightning.enabled = true;     
          $Lightning.setAnimationFrame(0);
          $Lightning.setVisible(true);
          $Lightning.playAnimation(LightningTest, false, 0, false);
     }
     else
     {
         //if we don't get that one out of 5, let's wait 256 ms and try again
         schedule(256, 0, lightningTimer);
     }
}

function t2dAnimatedSprite::onAnimationEnd(%this)
{
     //let's clean up that animation
     $Lightning.enabled = false;     
     $Lightning.setAnimationFrame(0);
     $Lightning.setVisible(false);

     //Let's start this thing all over again
     lightningTimer();
}

I put the exec code into game.cs, and I set a scene object with a class "Lightning" into my game. Nothing happens... I check the console and it says:

Unknown Command: setAnimationFrame
Unknown Command: playAnimation

I am not very good with activating animations, since I usually use the PSK behavior to do it for me...
#7
03/10/2009 (5:52 pm)
You probably want to just name your object instead of setting it's class. Name your object Lightning and then use Lightning.enabled = false; and so on without the $.
#8
03/10/2009 (6:14 pm)
Nope, it didn't work... Still the same thing for both.

I found another problem:

t2dStaticSprite::setFrame() - Cannot set frame without existing t2dImageMapDatablock Datablock!
#9
03/10/2009 (8:05 pm)
It probably doesn't work because you didn't create an animation named Lightning like Dustin recommended.

That error implies that you are calling setFrame on a static image, not an animation. You need to go in the editor, click on the create animation button and add some frames to create an animation. Take note of the name that is created in that box, it's your 'linkImageAnimationName'.
nameOfAnimation.playAnimation(linkImageAnimationName, false, 0, false);
Then drag the animation into your level, select it and go to the scripting rollout and name it 'Lightning', that's your .nameOfAnimation'.

See what happens then.
#10
03/11/2009 (1:42 pm)
Well, it worked! Thanks for the help, I thought that when it said:

t2dStaticSprite

It meant that it will replace the sprite with the animation... Guess I was wrong... Thanks though!

Is it possible to have the animation play another random one? I want to be able to let it randomly do 5 different types of lightning, it looks ugly doing the same thing every few seconds.
#11
03/11/2009 (1:48 pm)
Sure, I bet you could figure that out though.

function lightningTimer()
{
     //let's get that random number you wanted
     %random = getRandom(1,5);
     
     //if we get that one out of 5, let's play the animation
     if(%random == 1)
     {
          //prepare the animation for launch
          $Lightning.enabled = true;     
          $Lightning.setAnimationFrame(0);
          $Lightning.setVisible(true);
          $Lightning.playAnimation(LightningTest, false, 0, false);
     }
     else if(%random == 2)
     {
          //prepare the animation for launch
          $Lightning2.enabled = true;     
          $Lightning2.setAnimationFrame(0);
          $Lightning2.setVisible(true);
          $Lightning2.playAnimation(LightningTest, false, 0, false);
     
     //Repeat this if/else chain for all 5 animations
     //A better way would be to use a switch statement but I
     //don't really have time to explain it...

     }
     else
     {
         //if we don't get that one out of 5, let's wait 256 ms and try again
         schedule(256, 0, lightningTimer);
     }
}
#12
03/11/2009 (1:55 pm)
Fantastic! I was skeptical since I thought an animation could only play it's own animation.

Now I almost have the basics for my game...

Also, I will use a switch statement... I know how to use that.
#13
03/11/2009 (2:01 pm)
One things I found out the hard way is don't name your animations with numbers only. It simply doesn't work.