2

I have an object on canvas that I would like to move with keyboard events,

My event function is as follows

function onKeyDown(evt) {
if (evt.keyCode == 40) { downDown = true;}
if (evt.keyCode == 39) { rightDown = true;}
if (evt.keyCode == 38) { upDown = true;}
if (evt.keyCode == 37) { leftDown = true;}
}

and my onKeyUp function is the same except with false as the value

then I attach it as

$(document).keydown(onKeyDown);
$(document).keyup(onKeyUp);

I have a draw function that is called within my init as intv = setInterval(draw, 10); with the following statements

                            if (rightDown) { x += dx;}
                            if (upDown) { y -= dy;}
                            if (downDown) { y += dy;}
                            if (leftDown) {x -= dx;}

Everything except the -x direction (left Down) works well. Such that I can move the object up,right and down. When left is pressed the object continues moving left. Are my conditional statements setup improperly ?

The full demo is at http://jsfiddle.net/avSvu/

phwd
  • 19,975
  • 5
  • 50
  • 78
  • Could you post a demo? maybe on http://jsfiddle.net/ – Soumya Feb 10 '11 at 19:39
  • @Soumya92 http://jsfiddle.net/avSvu/ – phwd Feb 10 '11 at 20:00
  • Stupid little demo I made using two vars, don't know if it helps... (http://www.jsfiddle.net/bradchristie/jL2u2/1/) – Brad Christie Feb 10 '11 at 20:08
  • You don't need 4 variables to store the key-press information. Check out this answer: http://stackoverflow.com/questions/4950575/how-to-move-a-div-with-arrow-keys/4951670#4951670 One object stores the information for all 4 arrow keys. It makes the JavaScript code simpler, too. – Šime Vidas Feb 10 '11 at 20:23
  • @Šime Vidas Thanks that is a very neat thing, though I am still trying to figure out why one of the directions is not working properly. – phwd Feb 10 '11 at 20:36
  • @Philippe I think @Ivo found out why your code doesn't work... – Šime Vidas Feb 10 '11 at 20:37
  • @Šime yeah you are right – phwd Feb 10 '11 at 20:56

3 Answers3

3
function onKeyUp(evt) {
    if (evt.keyCode == 40) { downDown = false;}
    ...

    //      v----- capital K ?
    if (evt.KeyCode == 37) { leftDown = false;}
}

Live demo: http://jsfiddle.net/avSvu/5/

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
Ivo Wetzel
  • 46,459
  • 16
  • 98
  • 112
  • You nailed it, good job. I looked that over for a good 5 minutes and didn't see it. I blame jsFiddle's font selection. ;p – Brad Christie Feb 10 '11 at 20:26
  • @Philippe Check out the link in the answer above. It is your exact code but with the capital K corrected. As you can see, it works once you correct that. – Šime Vidas Feb 10 '11 at 20:46
  • I see it now oO I am so blind. Thanks again. – phwd Feb 10 '11 at 20:53
1

Your code can have improvements like you should not have to check the keycode every time and you can reuse the same function to turn flip the boolean flags.

<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8 />
    <title></title>
  </head>  
  <body>

    <div id="out1"></div>
    <div id="out2"></div>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>    
    <script type="text/javascript">


      (function(){

        var downDown = false;
        var rightDown = false;
        var upDown = false;
        var leftDown = false;

        function onKeyUpDown(evt,isDown) {
          var keyCode = evt.keyCode;
          jQuery("#out1").html(keyCode);
          if (keyCode  == 40) { downDown = isDown;}
          else if (keyCode == 39) { rightDown = isDown;}
          else if (keyCode == 38) { upDown = isDown;}
          else if (keyCode == 37) { leftDown = isDown;}
        }

        jQuery(document).keydown( function(evt){onKeyUpDown(evt,true);}).keyup( function(evt){onKeyUpDown(evt,false);});

        window.setInterval(
          function(){
            var upDownTxt = upDown?"up":"-"; ;
            var downDownTxt = downDown?"down":"-";
            var leftDownTxt = leftDown?"left":"-";
            var rightDownTxt = rightDown?"right":"-";
            jQuery("#out2").html(upDownTxt + "<br/>" + downDownTxt + "<br/>" + leftDownTxt + "<br/>" + rightDownTxt );
          },
          100);

      })();

    </script>    
  </body>
</html>

http://jsbin.com/edavi3/edit

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • That is very good thanks, though I am still not understanding why one of the directions are not working while the others are. – phwd Feb 10 '11 at 20:38
1

Here, I re-factored your code:

$(function() {
    var x = 150,
        y = 150,
        dx = 2,
        dy = 2,        
        canvas = $('#canvas'),
        ctx = canvas[0].getContext('2d'),
        width = canvas.width(),
        height = canvas.height(),
        keys = {},
        intervalId = 0;

    function circle(x, y, r) {
        ctx.beginPath();
        ctx.arc(x, y, r, 0, Math.PI * 2, true);
        ctx.closePath();
        ctx.fill();
    }

    $(document).keydown(function(e) { keys[e.which] = true; });
    $(document).keyup(function(e) { keys[e.which] = false; });

    intervalId = setInterval(function() {
        ctx.clearRect(0, 0, width, height);
        x = x - (keys['37'] ? dx : 0) + (keys['39'] ? dx : 0);
        y = y - (keys['38'] ? dy : 0) + (keys['40'] ? dy : 0);
        circle(x, y, 10);
    }, 20);
});

Live demo: http://jsfiddle.net/avSvu/4/

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385