A Fuse Powered Company

Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Game loop is starting enterFrame trigger, but fps is not a constant
Started by mafonin Sep 12 2013 01:38 AM

4 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

mafonin

[GLOBAL: userInfoPane.html]
mafonin
  • Starter
  • Pip
  • 6 posts
  • Newbie

Good day everyone!

 

So, today when I was testing my game in samsung tab i saw that fps of the game could be either less or more and i can't control it ( in config i set fps=30).

 

So in main game loop I need to calculate physics ( Impulse and smth else) and make changes to elements in a game. And if fps is more my elements is faster and if it's fewer - it's lower.

 

It's really bad.

 

I tried to make calculation and setting of parameters by timer (100 ms loop)- but the game started "twitching"

 

as i see fps on my samsung could be 33 or more sometimes. And i think it could be the same problem on other devices.

 

How i could to find the solution of this problem ?

 

P.S. Sorry for my english if I have made mistakes )))

 



[TOPIC: post.html]
#2

craig stowers

[GLOBAL: userInfoPane.html]
craig stowers
  • Starter
  • PipPipPip
  • 42 posts
  • Advanced Member


local runtime = 0
local myObject = display.newGroup() --this could be any display object
myObject.xSpeed = 1
myObject.ySpeed = 0.5

local function getDeltaTime()
    local temp = system.getTimer()
    local dt = (temp-runtime) / (1000/60) --60fps or 30fps as base
    runtime = temp --Store game time
    return dt
end

local function frames(event)
    local dt = getDeltaTime()
    -- myObject.x = myObject.x + (myObject.xSpeed*dt)
    -- myObject.y = myObject.y + (myObject.ySpeed*dt)
    -- or the more efficient method is to translate your object
    myObject:translate( myObject.xSpeed*dt, myObject.ySpeed*dt)
end

Runtime:addEventListener("enterFrame", frames)

 

 

If you are pushing a device to it's limit and you want consistent on screen object speeds then you have to calculate the time between each frame - this is a little different to using a timer. Run an "enterFrame" event, but at the top of the function calculate the time between this frame and the last frame, then you can use this time to calculate how many 'virtual' frames have passed since the last enterFrame event. Apply this as a modifier when animating objects. In an ideal world it would always be 1 but as you have found it fluctuates wildly depending on the device.



[TOPIC: post.html]
#3

piotrz55

[GLOBAL: userInfoPane.html]
piotrz55
  • Starter
  • PipPipPipPipPipPip
  • 754 posts
  • Jedi

 And if fps is more my elements is faster and if it's fewer - it's lower.

It is normal and typical behaviour.

 

If you set fps in config, you are only limiting max fps - it means Corona will try to not exceed this value. However it doesn't mean you cannot have even 1 frame/sec. If you do heavy drawing and/or time consuming calculations Corona won't be able to keep desired value of 1/30th of second for frame.

 

It is the reason you do not make calculations based on fps. If you would move object by 1 pixel per frame then you would have object moving 30px/s. However if fps fluctuates then you won't have this 30px/s but varying values.

 

What you shoud do is to take time difference between frames and take it as you time parameter.

So you may write

t = ... -- calculated time between frames
object.x = 30 * t*0.001 -- time is usually in ms

 

and you will have 'smooth' animation not depending on varying frame rate

 

 

@craig stowers

Why dividing by 1000/60? It isn't correct value

 I think

local dt = (temp-runtime)*0.001

is enough because you usualy describe speed in px per second.

 

Your

local dt = (temp-runtime) / (1000/60)

in best case scenario (constant 60fps) would give you constantly value of '1'. Lower fps would give him only fraction of target fps (0, 1) range



[TOPIC: post.html]
#4

craig stowers

[GLOBAL: userInfoPane.html]
craig stowers
  • Starter
  • PipPipPip
  • 42 posts
  • Advanced Member

@piotrz55

 

I borrowed that code from here: http://www.coronalabs.com/blog/2013/06/18/guest-tutorial-delta-time-in-corona/

 

That method looks to me like it calculates the 'real' amount of frames that should have passed in that time, it makes it easy for people to apply it to existing code that is already frame based. i.e it won't muck up their tuned speeds etc.

 

Personally... if I went down this route I would code it purely on time alone and not bother working out how many "frames" should have passed. It really is irrelevant - just a different 'base' to work off.
 



[TOPIC: post.html]
#5

craig stowers

[GLOBAL: userInfoPane.html]
craig stowers
  • Starter
  • PipPipPip
  • 42 posts
  • Advanced Member

in best case scenario (constant 60fps) would give you constantly value of '1'. Lower fps would give him only fraction of target fps (0, 1) range

 

This is a little different. I believe when the frame rate dips the dt value will rise. So if a 60fps programmed game starts to chug and only runs at 30fps the dt value will rise to 2. Then if you use the dt as a modifier it will make your objects move twice what it usually would between those two frames in order to compensate for the lapsed time... make sense?




[topic_controls]
[/topic_controls]