Animation : difference between Runtime:addEventListener("enterFrame",fct) and performWithDelay(16,fct,0)

Hi all
I need to animate my game and please, I have 2 questions :

Question 1) for the 2 below functions :

  1. Runtime:addEventListener( “enterFrame”, fctAnime) -----> using fps = 60
  2. performWithDelay( 16, fctAnime, 0) -----> note that 1000 ms / 60 fps = 16,6

Imagine that my function fctAnime() last 1 full second (=1000 ms), so what will happen ?
With (1) and (2) then : several fctAnime() will be launched at the same time, or do fctAnime() have to be finished BEFORE another fctAnime() is able to start ?

Question 2) My second question is :
30 FPS (1 frame each 33 ms) is too slow for my game and 60 FPS (1 frame each 16 ms) is to speed.

How could i be able to launch my fctAnime() every 20 ms ?
Should I use performWithDelay like above, or runtime/enterframe and calculate inside if I could launch my animation code or if I should exit the function for this time to reach the speed I need?

Thanks

hi,

fctAnime is launch faster with Runtime because you will wait 16,6 millisecondes before the first execution of fctAnime with performWithDelay.

But the time between two frames with Runtime is ( I think ) equal to the delay between 2 consecutives works with performWithDelay


The fctAnime are not obliged to be finished in one frame.

for exemple, if you have 

local fctAnime=function() transition.to(myImage,{time=3000,x=400,y=400}) end

the fctAnime will translate in 3 seconds your image, but futur execution on futur frames will execute fctAnime and give image multiple transition


performWithDelay use a Runtime to works (check the enterFrame key on timer’s table).

And you will find by calculation that the diffence of timing between 2 frames is not exact (the clock inside the device is not always precise).

local last Runtime:addEventListener("enterFrame",function(event) print(event.time-(last or 0)) last=event.time end)

 With 30 fps, I obtain

31 46.1 15.4 19.4 42 31 18.400000000001 43.4 31 20.8 41.2 31 15.7 24.5 33.200000000001 33.2 32.9 23.2 31.3 38.6 30.7 38 31.2 34.400000000001 31 31 31

So if you want 20 fps precisely, it will be difficult.

Yvan.

Runtime:addEventListener(“enterFrame”) will always fire on 33ms or 16ms unless your code is stopping this (or you have so much graphics on screen that Coronas screen render is slowing).

If your code takes 1000ms to run it will make no difference how you call it.  Corona is single-threaded so if your code takes that long to run then NO other code will fire - either events or timers.

Normally games sync code to frame rate (and adapt using delta time if frame rate is not reliable)

I very much doubt you need 60 fps as at best this will just drain the mobile’s battery real fast.

Hi,

i really need more than 30 fps else my game is too slow.

To reach 40 FPS, i try this today :

I replace :

-- 60 FPS Runtime:addEventListener( "enterFrame", fctAnime )

With :

local frameCount = 0 local frameJump = 3 -- jump 1 frame every 3 frames function myEnterFrame()   frameCount = frameCount + 1   if frameCount \>= frameJump then     frameCount = 0   else     fctAnime()   end end -- end function myEnterFrame() -- 40 FPS Runtime:addEventListener( "enterFrame", myEnterFrame)

In first tests, it sounds like it’s great for what i need…

Ah I see what you are doing… you shouldn’t tie your animations to your frame rate they should be independent.

You need to use delta time to ensure the game runs independently to the frame rate.  This will explain the concept to you

thanks for the link, i know this tutoriel.

But unfortunately, i can’t move my object with a pos-xy*deltatime value, coz ALL the object on my screen must have the same pixel move each tip… (a move of exactly 5 pixels each tips, for every objects on the screen)

FYI, If you move your objects via transitions then they will automatically factor in delta time.

hi,

fctAnime is launch faster with Runtime because you will wait 16,6 millisecondes before the first execution of fctAnime with performWithDelay.

But the time between two frames with Runtime is ( I think ) equal to the delay between 2 consecutives works with performWithDelay


The fctAnime are not obliged to be finished in one frame.

for exemple, if you have 

local fctAnime=function() transition.to(myImage,{time=3000,x=400,y=400}) end

the fctAnime will translate in 3 seconds your image, but futur execution on futur frames will execute fctAnime and give image multiple transition


performWithDelay use a Runtime to works (check the enterFrame key on timer’s table).

And you will find by calculation that the diffence of timing between 2 frames is not exact (the clock inside the device is not always precise).

local last Runtime:addEventListener("enterFrame",function(event) print(event.time-(last or 0)) last=event.time end)

 With 30 fps, I obtain

31 46.1 15.4 19.4 42 31 18.400000000001 43.4 31 20.8 41.2 31 15.7 24.5 33.200000000001 33.2 32.9 23.2 31.3 38.6 30.7 38 31.2 34.400000000001 31 31 31

So if you want 20 fps precisely, it will be difficult.

Yvan.

Runtime:addEventListener(“enterFrame”) will always fire on 33ms or 16ms unless your code is stopping this (or you have so much graphics on screen that Coronas screen render is slowing).

If your code takes 1000ms to run it will make no difference how you call it.  Corona is single-threaded so if your code takes that long to run then NO other code will fire - either events or timers.

Normally games sync code to frame rate (and adapt using delta time if frame rate is not reliable)

I very much doubt you need 60 fps as at best this will just drain the mobile’s battery real fast.

Hi,

i really need more than 30 fps else my game is too slow.

To reach 40 FPS, i try this today :

I replace :

-- 60 FPS Runtime:addEventListener( "enterFrame", fctAnime )

With :

local frameCount = 0 local frameJump = 3 -- jump 1 frame every 3 frames function myEnterFrame()   frameCount = frameCount + 1   if frameCount \>= frameJump then     frameCount = 0   else     fctAnime()   end end -- end function myEnterFrame() -- 40 FPS Runtime:addEventListener( "enterFrame", myEnterFrame)

In first tests, it sounds like it’s great for what i need…

Ah I see what you are doing… you shouldn’t tie your animations to your frame rate they should be independent.

You need to use delta time to ensure the game runs independently to the frame rate.  This will explain the concept to you

thanks for the link, i know this tutoriel.

But unfortunately, i can’t move my object with a pos-xy*deltatime value, coz ALL the object on my screen must have the same pixel move each tip… (a move of exactly 5 pixels each tips, for every objects on the screen)

FYI, If you move your objects via transitions then they will automatically factor in delta time.