Need help with timer.performWithDelay()

Hey!

I’m working on a game where the player controls a rocket.

There is a problem with the way the explosion works at the moment:

There are six explosion sprites that show up along the length of the rocket.

I tried to add a 10ms delay to the creation of each sprite (so they don’t start animating simultaneously), but it does not appear to work in this case.

Am I misunderstanding how timer.performWithDelay works or what is the problem right now?

Thank you for helping!

EDIT: The problem persists even when the delays are much longer.

[lua]local function createExp( expNumber )
    – creates an explosion that is positioned along the rocket using expNumber
    – (this part works fine, so I left it out)
    
end

local function rocketExplode()
    createExp( 1 )
    timer.performWithDelay( 10, createExp( 2 ) )
    timer.performWithDelay( 20, createExp( 3 ) )
    timer.performWithDelay( 30, createExp( 4 ) )
    timer.performWithDelay( 40, createExp( 5 ) )
    timer.performWithDelay( 50, createExp( 6 ) )
    
end[/lua]

Welcome to the forums!

It has to do with frame rates.  If you have a 60 fps app, That means each frame is 16.667 milliseconds apart.Your first timer expires in the same frame as the non-timer based createExp(1).  3 and 4 happen in the same frame and so on. You only get one screen update per frame. In this case over 3 screen updates, all of these fire. If you’re app is a 30fps app, the first 4 all fire in the same frame. You entire animation starts is 0.05 / second.  I’d consider taking them up to at least 100 ms separation if not more.

Rob

The chances are that it is working but the delays are so short (only a 20th of a second between first and last) that it looks like it isn’t.  I’d start off with adding delays of 100, 200, 300 etc.  that would mean the final explosion is still only half a second after the first but should be more noticeable.  If that works then play about with the timings to see what looks best.

[edit]  Rob beat me to it :slight_smile:

Thank you both, that was helpful.

EDIT:

After changing the code to higher wait times there still isn’t any delay between the called functions, even on much higher times…

You’re right.

timer.performWithDelay() expects an address to  a function, not the return value of a function. When you do:

timer.performWithDelay( 10, createExp( 2 ) )

it executes createExp(2) and takes the return value and assigns that value to the timer to know what to run later. Your function doesn’t return anything so you effectively have

timer.performWithDelay( 10, nil )

When you put the () at the end of the function name it says to execute the function first then provide the address.  What you need in this case, since you need to pass in a parameter is an anonymous function

timer.performWithDelay( 10, function() createExp( 2 ); end  )

Simply wrap your function that needs to run with a parameter in an empty function wrapper and it will do what you want.

Rob

Beautiful! This did the trick.

Thank you very much for taking your time to explain it to me.

Welcome to the forums!

It has to do with frame rates.  If you have a 60 fps app, That means each frame is 16.667 milliseconds apart.Your first timer expires in the same frame as the non-timer based createExp(1).  3 and 4 happen in the same frame and so on. You only get one screen update per frame. In this case over 3 screen updates, all of these fire. If you’re app is a 30fps app, the first 4 all fire in the same frame. You entire animation starts is 0.05 / second.  I’d consider taking them up to at least 100 ms separation if not more.

Rob

The chances are that it is working but the delays are so short (only a 20th of a second between first and last) that it looks like it isn’t.  I’d start off with adding delays of 100, 200, 300 etc.  that would mean the final explosion is still only half a second after the first but should be more noticeable.  If that works then play about with the timings to see what looks best.

[edit]  Rob beat me to it :slight_smile:

Thank you both, that was helpful.

EDIT:

After changing the code to higher wait times there still isn’t any delay between the called functions, even on much higher times…

You’re right.

timer.performWithDelay() expects an address to  a function, not the return value of a function. When you do:

timer.performWithDelay( 10, createExp( 2 ) )

it executes createExp(2) and takes the return value and assigns that value to the timer to know what to run later. Your function doesn’t return anything so you effectively have

timer.performWithDelay( 10, nil )

When you put the () at the end of the function name it says to execute the function first then provide the address.  What you need in this case, since you need to pass in a parameter is an anonymous function

timer.performWithDelay( 10, function() createExp( 2 ); end  )

Simply wrap your function that needs to run with a parameter in an empty function wrapper and it will do what you want.

Rob

Beautiful! This did the trick.

Thank you very much for taking your time to explain it to me.