Making a canvas ball move smoothly


I wrote a multiplayer pong game, but because of a ~60ms lag my bouncing ball is not moving smoothly. The game itself is available here, but since it works only on chrome, and the site itself is written in my native language (also you obviously need two browsers in order for it to work), here is jsfiddle of the problem:

http://jsfiddle.net/yc6Lb/75/

As you can see in the fiddle, dx and dy are defined and the refreshes per second is defined as speed. I need those three variables to remain constant (I know that they are causing the ball to not move smoothly).

Now the question: Are there any tricks to not touch those variables, but make the ball look like it moves smoothly? I was thinking about rendering the new position of the ball + rendering previous position of the ball with 50% opacity, but I have yet to test it. Are there any other solutions to this problem?

I think, as @Jason said, that you could have the step as precise as you want in the animation (using animationFrame for instance), and handle separately the issue of getting the remote information.
However, for a quick fix you could use that trick i sometimes use : have a trail/shadow effect by clearing the context2d with lowered opacity.
So the clear function becomes :

function clear() {
  cxt.globalAlpha=0.3;
  cxt.fillStyle='#FFFFFF';
  cxt.fillRect(0, 0, WIDTH, HEIGHT);
  cxt.globalAlpha=1;
}

then you must not clear in the draw() function, and call to clear() in the draw loop.

i updated your fiddle :

http://jsfiddle.net/gamealchemist/yc6Lb/86/

play with the alpha to get the effect you want.

Rq : you might want to clear with full opacity some parts of the screen ( like the score ), and use lower opacity only in the animated part of the canvas.


This is ugly, but here's a FPS reference for you: http://jsfiddle.net/yc6Lb/84/

Specifically using requestAnimationFrame() and having a FPS counter. Note the performance difference :)

Here's a BEAUTIFUL CODE version: http://jsfiddle.net/neuroflux/Ey9uz/1/
You're most welcome!


You can gain a little bit of performance from not doing your 2*pi calc in every loop. Round it to a static value of 6.28.

You may also want to look at processing.js, which may speed things up.


There's nothing wrong with your math. You should be using requestAnimationFrame. Change your init function so that it looks like this:

function init() {
  window.requestAnimationFrame(init, cxt)
  draw();  
}

Here's a working JSFiddle example

You'll probably also need a polyfill for requestAnimationFrame to get it working on all browsers.