Timer improvements
Moderator: Moderators
Timer improvements
OnExpire
It'd be great if there was an automatic option to trigger something after the Timer has finished... I guess it's pretty obvious (I'd use it for bombs and similar situations). Similar to how AnimatorGroup has OnStop basically.
Of course the same effect can already be achieved in various clumsy ways, but they are all ugly...
It'd be great if there was an automatic option to trigger something after the Timer has finished... I guess it's pretty obvious (I'd use it for bombs and similar situations). Similar to how AnimatorGroup has OnStop basically.
Of course the same effect can already be achieved in various clumsy ways, but they are all ugly...
Last edited by rrTea on Mon Aug 08, 2016 12:59 pm, edited 5 times in total.
Re: Timer / OnExpire
I would probably just set the Timer.Interval=0 to disable it in a ZExpression in the Timer.OnTimer event. Is there a problem with that approach?
Re: Timer / OnExpire
That is smart. I haven't used timers much, instead doing them myself in code. But that should work well now that I know about it.
Re: Timer / OnExpire
But wouldn't that just stop the timer?VilleK wrote:I would probably just set the Timer.Interval=0 to disable it in a ZExpression in the Timer.OnTimer event. Is there a problem with that approach?
...I just saw that the Timer in the newest build has a "CurrentRelativeTime", so looks like this can be used in a condition (something like return (Countdown.CurrentRelativeTime == 0); + also check a flag to stop it from looping) so I tested it in
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
<OnUpdate>
<Timer Name="Countdown" Interval="1" RepeatCount="0"/>
<Condition>
<Expression>
<![CDATA[return (
Countdown.CurrentRelativeTime == 0);]]>
</Expression>
<OnTrue>
<ZExpression Expression="trace ("Here it is!");"/>
</OnTrue>
</Condition>
</OnUpdate>
<Content>
<ZExpression>
<Expression>
<![CDATA[trace (
intToStr(Countdown.CurrentRelativeTime*100)
);]]>
</Expression>
</ZExpression>
</Content>
</ZApplication>
Re: Timer / OnExpire
I would not use RepeatCount == 0 in condition, but rather put the desired behavior to OnTimer; it's more explicit. However, RepeatCount can be used for other things, see the following example:
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
<OnLoaded>
<ZExpression Comment="Init">
<Expression>
<![CDATA[Countdown.RepeatCount = -1;
Countdown.CurrentRelativeTime = 0;]]>
</Expression>
</ZExpression>
</OnLoaded>
<OnUpdate>
<Timer Name="Countdown" Interval="5" RepeatCount="0">
<OnTimer>
<ZExpression>
<Expression>
<![CDATA[trace ("Here it is!");
Countdown.RepeatCount = 0;
Countdown.CurrentRelativeTime = 6;]]>
</Expression>
</ZExpression>
</OnTimer>
</Timer>
</OnUpdate>
<OnRender>
<RenderText TextFloatRef="6 - Countdown.CurrentRelativeTime;"/>
</OnRender>
</ZApplication>
Re: Timer / OnExpire
Hi guys,
The CurrentRelativeTime property indicates how long ago the Timer has hit its interval. This is relevant because the moment when a interval has been completed usually doesn't match up exactly with the moment a frame is being executed.
For instance, imagine a Timer that spawns a model every second which has a Velocity.X of 1, a random Position.Y and renders a semi-transparent sprite. When you don't take CurrentRelativeTime in consideration and simply spawn a clone in OnTimer, you'll notice that the sprites are sometimes slightly apart or overlap slightly. But using CurrentRelativeTime you can correct this ( by offsetting the starting position ) almost perfectly.
Obviously you could also treat this kind of situation as a type of animation, to get it 100% right .. but the CurrentRelativeTime method is very useful for accurately spawning high-speed bullets at a set interval and such.
K
The CurrentRelativeTime property indicates how long ago the Timer has hit its interval. This is relevant because the moment when a interval has been completed usually doesn't match up exactly with the moment a frame is being executed.
For instance, imagine a Timer that spawns a model every second which has a Velocity.X of 1, a random Position.Y and renders a semi-transparent sprite. When you don't take CurrentRelativeTime in consideration and simply spawn a clone in OnTimer, you'll notice that the sprites are sometimes slightly apart or overlap slightly. But using CurrentRelativeTime you can correct this ( by offsetting the starting position ) almost perfectly.
Obviously you could also treat this kind of situation as a type of animation, to get it 100% right .. but the CurrentRelativeTime method is very useful for accurately spawning high-speed bullets at a set interval and such.
K
Re: Timer / OnExpire
Rado: Yes you're right, it's better to put it like in your example.
Kjell: Thanks for clarification, so that's what it's for!
In any case, just to attempt to clarify what I was talking about in the opening post: I was trying to say that adding the equivalent of AnimatorGroup's "OnStop" to Timer component would make Timer even more useful. (Edit: I added it to the old post.)
Kjell: Thanks for clarification, so that's what it's for!
In any case, just to attempt to clarify what I was talking about in the opening post: I was trying to say that adding the equivalent of AnimatorGroup's "OnStop" to Timer component would make Timer even more useful. (Edit: I added it to the old post.)
Last edited by rrTea on Mon Aug 08, 2016 1:02 pm, edited 1 time in total.
Re: Timer improvements
"Retrigger" timer
The name is a bit misleading but here is the situation I'm working on:
Player can do some stuff that adds to ComboCounter. As soon as the ComboCounter is bigger than 0, it should start falling every 1 second. Right now I'm dealing with it like this (from my main project):
The problem arises when the Player (it's encouraged actually) adds more Combo points before that 1 second expires. In such cases it looks bad when the counter first jumps up and immediately back down if it so happened that the Timer was at, say 0.2 when the new combo points got collected. What should happen is that the new addition of a combo point resets the Timer, but I can't find a way to do it. Is that even possible?
I tried a few things but nothing works.
Edit: Oh I just found an old topic that sounds similar to this:
viewtopic.php?p=5086#p5086
From what I understood of Kjell's explanation resetting the CurrentRelativeTime shouldn't do what I'm after?... I'll keep on poking tomorrow.
The name is a bit misleading but here is the situation I'm working on:
Player can do some stuff that adds to ComboCounter. As soon as the ComboCounter is bigger than 0, it should start falling every 1 second. Right now I'm dealing with it like this (from my main project):
Code: Select all
ZZDC<?xml version="1.0" encoding="iso-8859-1" ?>
<Condition Comment="Any combo?">
<Expression>
<![CDATA[return (
ComboCounter > 0
);]]>
</Expression>
<OnTrue>
<Timer Name="timer_ComboCountdown" Interval="0.2">
<OnTimer>
<ZExpression Expression="ComboCounter--;"/>
<Condition Comment="More than 40?">
<Expression>
<![CDATA[return (
ComboCounter > 40
);]]>
</Expression>
<OnTrue>
<PlaySound Sound="sfx_ComboCountdown" NoteNr="96"/>
</OnTrue>
</Condition>
</OnTimer>
</Timer>
</OnTrue>
</Condition>
I tried a few things but nothing works.
Edit: Oh I just found an old topic that sounds similar to this:
viewtopic.php?p=5086#p5086
From what I understood of Kjell's explanation resetting the CurrentRelativeTime shouldn't do what I'm after?... I'll keep on poking tomorrow.
Last edited by rrTea on Mon Aug 08, 2016 1:36 pm, edited 1 time in total.
Re: Timer improvements
Hi rrTea,
K
I'd recommend using a DIY-timer in these kind of situations.rrTea wrote:What should happen is that the new addition of a combo point resets the Timer, but I can't find a way to do it.
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" ClearColor="0.502 0.502 0.502 1" FileVersion="2">
<OnLoaded>
<ZExpression>
<Expression>
<![CDATA[// Reset the DIY-timer and combo-counter.
Timer = 0;
Combo = 0;]]>
</Expression>
</ZExpression>
</OnLoaded>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[// Drive DIY-timer
Timer += App.DeltaTime;
// Check if 1 second has passed
while(Timer > 1)
{
Timer--;
Combo++;
}
// Update combo string
RenderCombo.Text = intToStr(Combo);]]>
</Expression>
</ZExpression>
<KeyPress Keys="{" RepeatDelay="0.1">
<OnPressed>
<ZExpression>
<Expression>
<![CDATA[// Reset the DIY-timer
Timer = 0;]]>
</Expression>
</ZExpression>
</OnPressed>
</KeyPress>
</OnUpdate>
<OnRender>
<UseMaterial Material="DigitsMaterial"/>
<RenderText Name="RenderCombo" Text="0" Scale="5" RenderCharExpression="//"/>
</OnRender>
<Content>
<Variable Name="Timer"/>
<Variable Name="Combo"/>
<Group Comment="Digits">
<Children>
<Font Name="Digits" Bitmap="DigitsBitmap" FirstChar="48" CharPixelWidth="4" CharPixelHeight="5"/>
<Bitmap Name="DigitsBitmap" Width="20" Height="10" Filter="1">
<Producers>
<BitmapFromFile Transparency="2" HasAlphaLayer="1" DataWidth="20" DataHeight="10">
<BitmapFile>
<![CDATA[78DAFBFF1F011880E03F1A1F0670C913A31E9926479E9AEEC3A50F1DE0721F369A907D94F0D1DD488DF0C7C5C6172EA49887CDFD84E283909B88750FA5E1874E030044C69678]]>
</BitmapFile>
</BitmapFromFile>
</Producers>
</Bitmap>
<Material Name="DigitsMaterial" Shading="1" Light="0" Blend="1" ZBuffer="0" Font="Digits"/>
</Children>
</Group>
</Content>
</ZApplication>
Re: Timer improvements
Too bad Timer can't be used for that at the moment but this works too, thanks! I implemented it and it works. I'm planning to use it for other things too so I guess I'll just make all those timers like this.
Re: Timer improvements
Hi rrTea,
It's modeled after the Timer component, so ..
- When you use a interval of 1 second, the first time the timer is triggered is 1 second after the timer has started.
- When you use a repeat count of 2, the timer will trigger 3 times in total.
- When you use a interval that fits in the duration of a frame more than once, the timer still only triggers once per frame.
Make sure to call timerExecute every frame, and use timerAction to (UN)PAUSE or RESET the timer. If you want more ( or fewer ) features, want things to work differently or have any questions .. let me know
K
In that case you might want to wrap it into a ZLibrary ..rrTea wrote:I'm planning to use it for other things too so I guess I'll just make all those timers like this.
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
<OnLoaded>
<ZLibrary Comment="Timer">
<Source>
<![CDATA[//
const int _INF = 0xFF800000;
//
const int TIMER_PAUSE = 0x0,
TIMER_RESET = 0x1;
void timerAction(ref float timer, int action)
{
switch(action)
{
case TIMER_PAUSE:
if(timer != reinterpret_cast<float>(_INF))timer = 0-timer;
break;
case TIMER_RESET:
timer = 0;
break;
}
}
byte timerExecute(ref float timer, float interval, int repeat)
{
if(timer >= 0)
{
float t = floor(timer);
timer += interval > 0 ? App.DeltaTime/interval : 1;
if(floor(timer) != t)
{
if(repeat != -1)
{
if(t > repeat)
{
timer = reinterpret_cast<float>(_INF);
return 0;
}
}
return 1;
}
}
return 0;
}]]>
</Source>
</ZLibrary>
</OnLoaded>
<OnUpdate>
<Condition Expression="return timerExecute(Timer, 1, 2);">
<OnTrue>
<ZExpression Expression="trace(intToStr(Timer));"/>
</OnTrue>
</Condition>
</OnUpdate>
<Content>
<Variable Name="Timer"/>
</Content>
</ZApplication>
- When you use a interval of 1 second, the first time the timer is triggered is 1 second after the timer has started.
- When you use a repeat count of 2, the timer will trigger 3 times in total.
- When you use a interval that fits in the duration of a frame more than once, the timer still only triggers once per frame.
Make sure to call timerExecute every frame, and use timerAction to (UN)PAUSE or RESET the timer. If you want more ( or fewer ) features, want things to work differently or have any questions .. let me know
K
Excellent!
Hey Kjell, thanks so much! You're right it's probably best to have it in a library - it'll come in handy for combos, time trials and all the other things. I'll try to implement it as soon as I'm done with the video.