Search code examples
javascriptcanvaskeypress

Ball not moving smoothly


I wanted to do a simple moving ball, with the arrows, so I did:

<canvas id="canvas" width="300" height="300" ></canvas>

<script>
var x=120;
var y=120;
var key,pos=0;

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function()
{
    ctx.drawImage(img,x,y);
}
img.src="http://www.infogridpacific.com/blog/i/ball_online.png";

document.onkeydown=function(e)
{
    pos=1;
    key=window.event?e.keyCode:e.which;
}
document.onkeyup=function(e){pos=0;}

setInterval(function()
{
    if(pos==0)return;
    if(key==37)x-=2;
    if(key==38)y-=2;
    if(key==39)x+=2;
    if(key==40)y+=2;
    canvas.width=canvas.width;
    ctx.drawImage(img,x,y);
},5);
</script>

http://jsfiddle.net/mageek/ny3uz/6/

But if you do left then right, the ball stops for one second then start moving in the opposite direction. Any idea how to fix this?


Solution

  • I suspect you are probably still holding the left arrow key when you press the right arrow key, then let go of the left arrow slightly later.

    So the sequence of events goes like this:

    (you press left)             key=37 pos=1
    (ball moves left for a bit)
    (you press right)            key=39 pos=1
    (you let go of left)         key=39 pos=0
    (the ball stops moving)
    (1s later the OS autorepeat kicks in) key=39 pos=1
    (ball moves right)
    

    You need to keep track of how many keys have been pressed/released, and/or make use of the keycode in the up event to check which key was raised. Ideally, rather than just recording the value of the last keypress, keep track of all keys currently down.

    This version is completely smooth and also lets you move diagonally:

    var x=120;
    var y=120;
    var key = [];
    
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var img=new Image();
    img.onload=function()
    {
        ctx.drawImage(img,x,y);
    }
    img.src="http://www.infogridpacific.com/blog/i/ball_online.png";
    
    document.onkeydown=function(e)
    {
        code=window.event?e.keyCode:e.which;
        key[code]=1;
    }
    document.onkeyup=function(e)
    {
        code=window.event?e.keyCode:e.which;
        key[code]=0;
    }
    
    setInterval(function()
    {
        if(key[37])x-=2;
        if(key[38])y-=2;
        if(key[39])x+=2;
        if(key[40])y+=2;
        canvas.width=canvas.width;
        ctx.drawImage(img,x,y);
    },5);