How to Skip Frames in Canvas?

I am making a small game in HTML5 with the canvas elements. It runs great on MOST computers, but it is lags on others. However, it doesn't skip frames, it continues to render each frame and the game slows down. I am trying to write a function to skip frames, but I can't come up with a formula to do it.

I've tried searching around, but I have found nothing.

I have a function that renders the game called render and it is on a loop like this:

var renderTimer = setInterval("render(ctx)", 1000/CANVAS_FPS);

render()
{
/* render code here */
}


Thank you for any help, Brandon Pfeifer

Well I'm not a HTML5 or Canvas-expert but my guess is that you're doing everything every single frame (every main loop run)? In that case, split the game logic from the rendering logic. Make your game logic refresh every round in your main loop and then keep tabs on when to update the rendering. When the rendering should happen, just switch it on and supply it the current state of the game. Did that make any sense? :)

Thanks for the advice, I'm not sure why, but when I tried seperating the logic and the render, it did not help the performance. My theory is that Javascript can only do one line/command or one loop at a time. So it slows down regardless. However, I did find a way to skip frames. I'll post the psuedo code incase anyone wants it for their projects.

Let's say a slower computer renders 60 frames in 1500 milliseconds. (1.5 Seconds) In a perfect world this computer would render 60 frames in 1000 millisconds. (1 Second) In theory the slower computer is causing the logic portion of the game to fall behind at around 500 milliseconds per 60 frames rendered. To fix this we need to skip frames. 

First we need to calculate the average milliseconds per frame for the slower computer:

(1500/60) = 25 Milliseconds Per Frame

Then we need to calculate the average milliseconds per frame at perfect speed:

(1000/60) = 16.6 Milliseconds Per Frame

Now we need to calculate how many frames to render per second:

(1000/25) = 40

So the slower computer can only run the animation at 40 FPS.

So the slower computer needs to skip around 20 FPS.

If you benchmark every 60 rendered frames, it should be able to calculate the correct amount of frames toskip in every scene.

 

Hopefully that helps someone, I had to make up that formula. I couldn't find it anywhere else .

Also you need to calculate when to skip those frames. You can't have it skip 20 frames all at once. 

60/20 = 3

So you should skip every 3 frames.

 

 

I hope I helped someone.

see also:

http://creativejs.com/resources/requestanimationframe/

 

There are deeper implications than frameskip here -- on fast machines you may be rendering "too many" frames. And on portable devices, you can significantly impact battery life. Modern OSs actually have a javascript "timer" that "downclocks" the javascript timer when running on battery..... but requestAnimationFrame may be something you want to look into.

http://paulirish.com/2011/requestanimationframe-for-smart-animating/

See also Paul Irish for an excellent polyfill. He has a video where he talks a lot about this, and it has a lot of good information, but I can't find it at the moment.

 

 

 

 

p.s. chrome has an excellent code profiler that will let you see where things may be bogging down.

 

 

Thank You! Thank You! So much. I was wondering. See, I have a good Desktop and it runs the game perfectly. No stutters no flaws. However, My laptop is on the lower end of things. My brother's laptop is somewhat in the inbetween.

I was doing some measurements of time using (new Date().getTime()) and both laptop's were saying that they were rendering at the same amount of time. (I measured it in total time it took to render 60 frames.)  However, since my brother's laptop was rendering much much quicker. So much quicker, that the logic was being done quicker too. Even with my frameskipping algorithm!

I was all about to give up, but then you came along and showed me the solution. Thank you!

I am a C++ Programmer by heart and I am used to using System Metrics and its amazing/outstanding ability to keep track of time. It can keep track of time, down to the 10,000ths of a second. So, this Javascript timing really got me.

Thanks, also I have a question. Are you the Wendell from TekSyndicate?

Also, I love the code profiller in Chrome. It shows almost everything an actuall debugger does. It shows exactly where the errors happen. It is wonderful. I also use FireBug for FireFox, it isn't as good, but it gets the job done.

Thanks, also I have a question. Are you the Wendell from TekSyndicate?

yep.

look into the stuff on google chrome experiments. the ones that aren't webgl will have a lot of good interesting things from which you can learn. http://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage

 

I will definitely look at that website. My theory, is that if there is anything I can do to make my code better. I will do it. I like WebGl, but I need IE to support it before I look into it. :( (Still too many people using IE and I want to target as many people as possible. Sometimes, its a sad world we live in.)

I also had time to look into the links that you sent me. They were really good. I had looked at requestAnimationFrame once before, but tutorial I used just threw it into a while loop. :O So that website is amazing.

Edit: Also, in a couple weeks or so, I hope to have a working and stable alpha. I hope you get to see it.


Also, I am glad/happy/excited that you responded to me. A lot of people similar to you and Logan have minimal interaction with their users. And even when they do respond to their users, they do it in a mean way. However, I have yet to see that with you guys and it is hard for me to beleive that you spent time out of your day to type up a thought out response to my question. To me that shows that not only do you guys care about TekSyndicate, but it's community as well.


Also nice job with the website. I personally turn off my Ad-Blocker for it. I had to build a couple websites over the summer. It was a pain. Also, people don't understand that Weebly doesn't have PHP or MySql.


One Last Thing, I also value your commentary on tekSyndicate. You explain the more technical view points. You and Logan almost contrast each other, however that makes you and him a great team.

Edit: To put it simply, in relation to a car, Logan is the driver, while you are the engine. Both are equally important.