Maintaining a consistent frame rate with HTML5

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
ajtgarber
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 97
Joined: Wed Jun 10, 2009 8:56 am

Maintaining a consistent frame rate with HTML5

Post by ajtgarber »

I've been having trouble trying to maintain a consistent frame rate with HTML5 (I'm using Firefox right now, when I get back home I'll be using Chrome). In order to get my frame updates
I've been using javascript's setInterval function, and to combat the inconsistencies of the times my function is called I've been using a delta value. This is my first time using a delta value,
so I probably missed something, any help would be appreciated.

The script:

Code: Select all

var canvas = document.getElementById("testCanvas");
			var g = canvas.getContext("2d");
			
			setInterval(update, (1000/60));

			var x = 50;
			var xvel = 2;
			var lastTime = new Date();
			var oneFrame = (1000/60); //we want 60 fps, so divide one second by 60
			var extra = "";

			function update() {
				var currTime = new Date();
				var delta = currTime.getMilliseconds()-lastTime.getMilliseconds();			

				var incrementAmount = ((xvel/oneFrame)*Math.abs(delta));
				x += incrementAmount;

				if(x > canvas.width-25) {
					xvel = -xvel;
					x = canvas.width-25;
				} else if(x < 0) {
					xvel = -xvel;
					x = 0;
				}

				paint();
				lastTime = new Date();
			}

			function paint() {
				g.clearRect(0, 0, canvas.width, canvas.height);

				g.strokeStyle = "#000000";
				g.strokeRect(0, 0, canvas.width, canvas.height);

				//actually draw our square
				g.fillStyle = "#0000FF";
				g.fillRect(x, 25.5, 25, 25);

				g.fillText("x: "+x+", extra: "+extra, 5, canvas.height-25);			
			}
EDIT: I should have also mentioned that the main reason I'm asking this question is because the above code randomly decides to jump about 70 pixels, along with being jittery
User avatar
szdarkhack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 61
Joined: Fri May 08, 2009 2:31 am

Re: Maintaining a consistent frame rate with HTML5

Post by szdarkhack »

Here's one issue that i spotted, it may be partly responsible for your problem. At the end of your Update function, you set lastTime to a new Date object. Doing so means that you are effectively skipping most of the function in your delta calculation. What i mean is that you are measuring time from the END of the last Update to the START of the new one, not taking into account the time it takes for the function itself to run.

The fix for this would be to set lastTime = currTime, this will make it count time from delta calculation to delta calculation, including everything in between.
ajtgarber
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 97
Joined: Wed Jun 10, 2009 8:56 am

Re: Maintaining a consistent frame rate with HTML5

Post by ajtgarber »

Thanks, it doesn't seem to have fixed it though. For some reason it moves the square smoothly for about a few seconds then makes a large jump, moves smoothly then jumps again, and so on (as before).
User avatar
szdarkhack
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 61
Joined: Fri May 08, 2009 2:31 am

Re: Maintaining a consistent frame rate with HTML5

Post by szdarkhack »

Hah, i found it :)

http://www.w3schools.com/jsref/jsref_ge ... econds.asp

As you can see by following the link, the Date.getMilliseconds() method does NOT return the total milliseconds since Jan 1, 1970 (like the C++ clock() does for example). Instead, it returns the milliseconds *within* the CURRENT second. As in, if you had a clock with a millisecond hand, it would be it's position, not the TOTAL amount of milliseconds. Therefore, whenever you start one frame just below 1000 milliseconds and the next one just above that, it wraps around to 0 again, thus causing your numerical issues.

I believe the appropriate method you want is Date.getTime() (http://www.w3schools.com/jsref/jsref_gettime.asp). This one DOES return the total milliseconds since Jan 1, 1970 and does not wrap around every second that passes. That should solve your problem :)
Post Reply