Skip to content

46. Timers

April 30, 2013

This post is about timers, measuring frames per second, keeping a constant speed in your animation – and it’s connected by time, and useful techniques.

The tools we will end up with

  • How to make something happen every X seconds
  • How to measure how fast Codea is redrawing the screen
  • How to avoid slowing of your animation, even if Codea is drawing slowly

I’ll remind you of a few other things we’ve covered in the past, too, so there’s quite a lot in here. But it’s mainly about time.

Making something happen every X seconds

This is fairly easy.

First, you need code that checks often whether X seconds has passed. Where should you put it? There is really only one answer – in the draw function.

Second, what timer are you going to use?

The ElapsedTime function gives you the time in seconds since the program started running. So if you want something to happen every 5 seconds, you could write

    --in setup

    --in draw
    if ElapsedTime>t then
        --do something

So this code stores a time 5 seconds from now, and waits for ElapsedTime to reach it. Then it resets it and waits again, and so on.

The DeltaTime function gives you the time (in fractions of a second) since the last redraw, and you use it slightly differently, because it is not a cumulative figure.

    --in setup

    --in draw
    t=t+DeltaTime --add time since last redraw
    if t>5 then
        --do something

So t keeps a count of total time elapsed, and when it exceeds 5 seconds, we do something, then we deduct 5 seconds from t (we could set it to 0, but that is slightly less accurate).

Measuring Codea’s drawing speed (FPS)

This becomes important if you start doing heavy calculation work, eg in 3D. You need to keep an eye on speed and cut down on things that affect it badly. The easiest way is to set up a parameter which you can see at all times, and and calculate the FPS in the draw function.

The simplest calculation is FPS = 1/DeltaTime, which bases the speed on a single observation. You will soon find this bounces around too much, and you need to average it.

The simplest averaging method is to make a table of the most recent N observed speeds, and average them. This is somewhat cumbersome, though, even though Lua’s tables make it easy to add new observations and delete the oldest ones.

    --FPS_table holds the last 10 observations in this example
    --FPS is the average of these 10 values
    FPS_table[#FPS_table+1]=1/DeltaTime --add newest observation to end of table
    --adjust average - no need to add then all up and divide by 10
    --instead, just add latest observation and remove oldest one from average
    FPS=(FPS*10+1/DeltaTime-FPS_table[1])/10 --adjust average
    table.remove(FPS_table,1) --remove oldest observation

Another method, suggested by JMV38, a Codea user with a self confessed passion for optimising FPS, is to just store the last FPS figure, then multiply it by 0.9 and add 0.1 x the new observed figure. This is not too far from using the average of the past 10 observations, and is probably the simplest approach.

    FPS = FPS*0.9+ 1/(DeltaTime)*0.1

All three methods are demonstrated in the code at bottom. The last one seems to be most popular among Codea users.

Keeping a constant speed in your animations

As your animations get more complex, you may find they slow down as the interval between redraws increases.

Suppose you were using code like this

    x=x + dx --adjust x position by current speed

then if your redraw speed slows down, the objects on your screen will slow down too.

Here is a way to prevent this. First, define your speed in pixels per second, eg if your speed was 5 pixels per redraw, call it 300 instead (5 x 60 redraws/second).

    --dx is now 300
    x=x + dx * DeltaTime

Now, if Codea starts running slowly, redraws will be less frequent, but DeltaTime (the time between redraws) will increase, and make up for this.

Suppose (for simplicity) Codea is running at 30 redraws/second, half the usual speed. DeltaTime will be 1/30 instead of 1/60, so x will be adjusted by twice the normal amount, and the objects will continue to move at their original speed over any given time period.

There is a downside, which is that the movement can begin to look jerky.

You can see all of this in the sample code at bottom, which has a “Smoothing” switch, which, if turned on, lets you see what happens if you use DeltaTime. You probably wont see much difference until the FPS is below 40.

This is a really useful technique to learn, even if you don’t need it most of the time.

Sample code

I’ve provided a sample project below which creates 10 random balloons every second, using a timer. The balloons move randomly around the screen.

FPS is provided in each of the three ways described above, and as the number of balloons exceeds 100, you should see it starting to fall.

I’ve put the FPS function in their own table, for no other reason to remind you can do this, ie wrap up a set of useful functions into their own table, so the function names and variables don’t clash with any of the other code in your project, making it easy to pick it up and drop it into any other project without problems. (Did you know? Codea stores classes in tables, behind the scenes).

The code is here.


From → Programming

  1. Ken Duerden permalink

    I am admiring your efforts with 3D which is way beyond my current paygrade 🙂 This post on time is bloody fantastic. Many thanks for this and once again what an outstanding resource this has become. Please keep going 🙂

    • Don’t be too impressed. I’m at the very edge of my competence and I don’t necessarily understand all of my own code – and I can only admire people who actually work in 3D. (But then, it seems the only way they can do it is by specialising heavily, eg in doing water, or people’s hair, or lighting, etc).

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: