TimeDelta, part two.

For questions about using Classic.

Post » Thu Apr 15, 2010 3:54 am

About a year ago i posted asking for help with TimeDelta. It took a while, but eventually you guys managed to get me on my way...

Then i did some other stuff for a year, and now i am back, and i don't have a clue about TimeDelta again.

Would anyone who knows how it works mind throwing together some practical examples?
Perhaps a grenade like arc? That's what i am trying to do at the moment, but it would be really useful to have a good selection of practical implementation examples.

How to use Timedelta to count up/down private variables
How to use Timedelta to move objects correctly etc


Cheers for any help,
Steven
B
9
S
2
G
4
Posts: 346
Reputation: 2,726

Post » Thu Apr 15, 2010 5:52 am

There is not much to TimeDelta. It isn't really complicated.

The game time advances in ticks. A tick is a slot, giving you the chance to compute things (using ACE).
The duration of a tick is of a variable time, because sometimes there is much to do for Construct, sometimes not.
TimeDelta is the duration of one tick. If you add all TimeDeltas from every tick, the all sum up to 1 per second. So TimeDelta is a fraction of a second.
To alter things over time, you just use the following formula in every tick:

AmountPerTick = TimeDelta * DesiredAmountPerSecond

To move a sprite 75 pixels per second you'd use TimeDelta * 75
To turn a sprite 87 per second you'd use TimeDelta * 87
To represent the evolving cast time of a spell that lasts 2 seconds (2 seconds being 100%) you'd use TimeDelta * 50

and so on
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Thu Apr 15, 2010 7:28 am

Say i have :
(Always - Add 1 to "Move")
The game is running at 1000fps, so that after a second "Move" would be 1000 right?

So i would need to "Timedelta" it.

(Always - Add 1*Timedelta to "Move")
So here, it is adding 1/1000 every 1/1000 of a second, so it would equal 1?

And now i want something to move based on this value

(Always - Set position of "Object" to "Object.X" + "Object value('Move')")

Do i need to add Timedelta into this line?


I have something similar to this in my current project, and depending on the frame rate it runs completely differently. I think the main issue i am having is understanding how and where to use Timedelta, not what it is.



"To represent the evolving cast time of a spell that lasts 2 seconds (2 seconds being 100%) you'd use TimeDelta * 50"

I only just realised that it is being multiplied by a % in this line, I get the concept, but i don't know how you would actually create this situation.
B
9
S
2
G
4
Posts: 346
Reputation: 2,726

Post » Thu Apr 15, 2010 11:34 am

[quote="Steven":21hkpwsk]Say i have :
(Always - Add 1 to "Move")
The game is running at 1000fps, so that after a second "Move" would be 1000 right?[/quote:21hkpwsk]
Correct.

[quote="Steven":21hkpwsk]So i would need to "Timedelta" it.

(Always - Add 1*Timedelta to "Move")
So here, it is adding 1/1000 every 1/1000 of a second, so it would equal 1?[/quote:21hkpwsk]
Yes, if Construct can work reliably in only one millisecond :wink:

[quote="Steven":21hkpwsk]And now i want something to move based on this value

(Always - Set position of "Object" to "Object.X" + "Object value('Move')")

Do i need to add Timedelta into this line?[/quote:21hkpwsk]
It depends on what you want to achieve. If you want the object to move 1 pixel per second, then you are doing it wrong. The correct line for this would be:

Always - Set position of "Object" to "Object.X" + TimeDelta

This way, the object is moved one pixel per second, no matter what the current frame rate is.

Let us make an easier example to see, why your approach is going wrong.
TimeDelta always equals 10
object.x is 0 at start
We want object.x to move by 10 every tick

First tick
You are adding 10 to move. move = 10
a) You are adding move to object.x. object.x = 10
b) I am adding TimeDelta to object.x. object.x = 10

Second tick
You are adding 10 to move. move = 20
a) You are adding move to object.x. object.x = 30
b) I am adding TimeDelta to object.x. object.x = 20

Third tick
You are adding 10 to move. move = 30
a) You are adding move to object.x. object.x = 60
b) I am adding TimeDelta to object.x. object.x = 30

See?
You could instead of adding to .x just replace .x with 'move'. That's the equivalent to my line of code. So:
Always - Set position of "Object" to "Object.X" + TimeDelta
and
Always - Set position of "Object" to "Object value('Move')"
are the same in your example

[quote="Steven":21hkpwsk]"To represent the evolving cast time of a spell that lasts 2 seconds (2 seconds being 100%) you'd use TimeDelta * 50"

I only just realised that it is being multiplied by a % in this line, I get the concept, but i don't know how you would actually create this situation.[/quote:21hkpwsk]
I've setup a simple cap showing this in action. That's the most easiest way I think.
Example (done with .84)
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Thu Apr 15, 2010 12:26 pm

Have you read the TimeDelta article in my signature? It should cover it as you want. The idea is that objects move at a constant speed in real-world time, independent of the framerate, rather than speeding up if the framerate is higher. So:

Set X to .X + 1

Every second, this will move the object 1000 pixels sideways at 1000fps and 10 pixels sideways at 10fps. A difference of 100x in speed depending on the framerate!

Set X to .X + 1 * TimeDelta

This will move the object precisely one pixel every second, no matter the framerate. Obviously multiplying by 1 is redundant, but it makes it clear that it's one pixel per second.

If that number is a private variable or some such, you still need the TimeDelta! It makes no difference if that number is hard-coded or a variable, you'd still need to do it like this:

Set X to .X + Object('Speed') * TimeDelta
Scirra Founder
B
359
S
214
G
72
Posts: 22,952
Reputation: 178,600

Post » Thu Apr 15, 2010 12:41 pm

TimeDelta is the amount of time that has passed during the previous loop of the game engine.
[list:133jkltd]
[*:133jkltd]For one second in game time, the sum of the TimeDeltas from all of the frames in that second will equal 1.[/*:m:133jkltd]
[*:133jkltd]If your game was running at a consistent 50fps, TimeDelta for one of those frames would be 0.02 (1/50).[/*:m:133jkltd]
[*:133jkltd]Anything time based (movement, rotation, etc.) should be set to the amount you want it to change per second. For example, 200 pixels per second would be a nice number for movement speed.[/*:m:133jkltd]
[*:133jkltd]When you multiply that by TimeDelta, you end up with the correct change per frame, regardless of the actual frame rate. [/*:m:133jkltd][/list:u:133jkltd]

So, at 50fps TimeDelta would be 0.02, each frame the object would move 200pixels*0.02 = 4 pixels. However, if the game was running at 100fps then TimeDelta would be 0.01 (1s/100f); 200*0.01 = 2 pixels. This table shows how TimeDelta keeps things like movement consistent:

[code:133jkltd]fps TD Speed (pps) Distance per frame Distance per second
25 0.04 200 200 * 0.04 = 8 8*25 = 200
50 0.02 200 200 * 0.02 = 4 4*50 = 200
100 0.01 200 200 * 0.01 = 2 2*100 = 200[/code:133jkltd]

Frame rates won't always be consistent, but TimeDelta will always represent the relative time taken by each frame, so the results will always be consistent.

Just remember- if it is changing over time, use the amount you want it to change in one second and multiply it by TimeDelta.
B
2
S
2
G
3
Posts: 105
Reputation: 1,510

Post » Thu Apr 15, 2010 3:00 pm

[quote="Ashley":3sev1g14]If that number is a private variable or some such, you still need the TimeDelta! It makes no difference if that number is hard-coded or a variable, you'd still need to do it like this:

Set X to .X + Object('Speed') * TimeDelta[/quote:3sev1g14]
Don't confuse him. In his example, that was not the problem. TimeDelta was already taken account of and stored within the variable ("Add 1*TimeDelta to 'Move'"). If he would now multiply it with TimeDelta again, he would get wrong results...
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Thu Apr 15, 2010 4:16 pm

Ooh OK. Well, there's several explanations in this thread now :)
Scirra Founder
B
359
S
214
G
72
Posts: 22,952
Reputation: 178,600

Post » Fri Apr 16, 2010 7:13 am

Ashley - Cheers for stopping by again :P I hadn't looked at the Timedelta article recently, whether or not it has been updated in the last year, or i understand things a little better, it does seems better this time around.

However,[quote="tulamide":3s5nv4uy][quote="Ashley":3s5nv4uy]If that number is a private variable or some such, you still need the TimeDelta! It makes no difference if that number is hard-coded or a variable, you'd still need to do it like this:

Set X to .X + Object('Speed') * TimeDelta[/quote:3s5nv4uy]
Don't confuse him. In his example, that was not the problem. TimeDelta was already taken account of and stored within the variable ("Add 1*TimeDelta to 'Move'"). If he would now multiply it with TimeDelta again, he would get wrong results...[/quote:3s5nv4uy]

+ Every Tick
> Add 500 * TimeDelta to 'Y Speed' (the acceleration)
> Set Y to .Y + 'Y Speed' * TimeDelta (the speed)

That there is from the Timedelta article, is it not multiplying by Timedelta twice?

Thanks chaps for the detailed break down of what timedelta is.

And Tulamide, I downloaded the example, and damn, my 'code' looks disgusting now. Aside from the fact you make timedelta work right, it is so tidy and effective. I am going to play around with Timedelta in a fresh cap(I think i will start my project over again) and will try to incorporate the tidiness alongside the timedeltaness.

Will post my attempts.

http://dl.dropbox.com/u/1487524/TimeDelta/TimeDelta.cap

There is something horribly wrong in my process.
B
9
S
2
G
4
Posts: 346
Reputation: 2,726

Post » Fri Apr 16, 2010 8:06 am

[quote="Steven":2jt20yi9]+ Every Tick
> Add 500 * TimeDelta to 'Y Speed' (the acceleration)
> Set Y to .Y + 'Y Speed' * TimeDelta (the speed)

That there is from the Timedelta article, is it not multiplying by Timedelta twice?[/quote:2jt20yi9]
We are talking about different approaches here. In your example it was all about a constant movement, whereas the above example generates a variable (accelerating) movement. The latter is what I wanted to show with the simplified comparison of your approach and mine a few posts above.

Remember the formula?
AmountPerTick = TimeDelta * DesiredAmountPerSecond

If DesiredAmountPerSecond is a constant value you only apply TimeDelta once. If you want it to change over time, you force another TimeDelta calculation. Let's say, DesiredAmountPerSecond shall raise by a constant value per second, then the formula is:

DesiredAmountPerSecond = DesiredAmountPerSecond + TimeDelta * DesiredRaisePerSecond

putting this into the first formula:
AmountPerTick = TimeDelta * (DesiredAmountPerSecond + TimeDelta * DesiredRaisePerSecond)

This can be stacked endlessly. Maybe DesiredRaisePerSecond shall lower over time. That would be:

DesiredRaisePerSecond = DesiredRaisePerSecond - TimeDelta * DesiredLoweringPerSecond

putting this into the first formula:
AmountPerTick = TimeDelta * (DesiredAmountPerSecond + TimeDelta * (DesiredRaisePerSecond - TimeDelta * DesiredLoweringPerSecond))

There are easier ways for acceleration or deceleration or smoothing, etc., this is just to show the "straight forwardness" of using TimeDelta :)
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Next

Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 5 guests