Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I move my JS objects smoothly using keyboard input?

So I am new to HTML5 and decided to start to code a pong game. I want to move my characters smoothly using my keyboard, the W and S keys for the one on the left and the Up and Down arrows for the one on the right. I can't seem to get it to work. It's probably quite easy, but me being the noob I am, I need a bit of help. Thanks in advance!

<!DOCTYPE html>
<html>
  <head>
      <title>Pingedy Pong</title>
  </head>
  <body style="font-family:Arial;">
      <canvas id="ctx" width="699" height="400" style="background-color:black;border:2px solid black;background-image: url('background.jpg');"></canvas>
      <script>
        
        // STARTING SCRIPT
          
        var ctx = document.getElementById("ctx").getContext("2d");
        ctx.fillStyle="white";
        ctx.font = '30px Arial';
        
        // VARIABLES
          
        var keys1 = [];
        var keys2 = [];
          
        var width = 699;
        var height = 400;
          
        var ball = {
            width:20,
            height:20,
            spdX:2.9,
            spdY:2.9,
            x:340,
            y:190,
        };
          
        var char1 = {
            w:15,
            h:90,
            spdX:3,
            spdY:3,
            x:10,
            y:155,
        };
          
        var char2 = {
            w:15,
            h:90,
            spdX:3,
            spdY:3,
            x:674,
            y:155,
        };
          
          // UPDATE
          
          function updateEntity(a) {
            a.x+=a.spdX;
            a.y+=a.spdY;
            ctx.clearRect(0,0,width,height);
            ctx.fillRect(a.x,a.y,a.height,a.width);
              if(a.x > width-a.width || a.x < 0) {
                a.spdX = -a.spdX;
              };
              
              if(a.y > height-a.height || a.y < 0) {
                a.spdY = -a.spdY;
              };
          };
          
          function renderChar(b) {
            ctx.fillRect(b.x,b.y,b.w,b.h);
          };
          
          function checkInput() {
            document.addEventListener('onkeydown', function(e) {
                if(e.keyCode == 37) {
                    char1.y += 1;
                }
                else if(e.keyCode == 39) {
                    char1.y -= 1;
                }
            });
          };
          
          function checkWinP1() {
              if (ball.x < 0.33) {
                console.log("P1 Wins");
              };
          };
          function checkWinP2() {
              if (ball.x > 679) {
                console.log("P2 Wins");
              };
          };
          
          function update() {
            updateEntity(ball);
            renderChar(char1);
            renderChar(char2);
            checkInput();
            checkWinP1();
            checkWinP2();
          };
          
          //TICKS
          
          setInterval(update,1000/120);
             
     </script>
  </body>
</html>
like image 899
Jake Avatar asked Nov 09 '22 06:11

Jake


1 Answers

UPDATE 1: use keydown instead of keypress event.

The reason for this update is that arrow keys don't trigger the keypress event (or they trigger it but the event doesn't return information about which key was pressed). Read this when you want more information about it.


UPDATE 2

I realize now the 'smoothly' keyword in your question. If to call the update function with a short interval is not good enough for you, requestAnimationFrame() API is the way to go.


When you are programming a game, I advice you to use jQuery.

Try this code:

var characterSpeed = 15;

$(document).on("keydown", function (e) {
    switch (e.which)
    {
        case 87: //w
            char1.y -= characterSpeed;
            break;
        case 83: //s
            char1.y += characterSpeed;
            break;
        case 38: //up arrow
            char2.y -= characterSpeed;
            break;
        case 40: //down arrow
            char2.y += characterSpeed;
            break;
        default:
            alert("You have pressed the key " + e.which);
     } 
});

Here you have the snippet:

// STARTING SCRIPT
          
        var ctx = document.getElementById("ctx").getContext("2d");
        ctx.fillStyle="white";
        ctx.font = '30px Arial';
        
        // VARIABLES
          
        var keys1 = [];
        var keys2 = [];
          
        var width = 699;
        var height = 400;
          
        var ball = {
            width:20,
            height:20,
            spdX:2.9,
            spdY:2.9,
            x:340,
            y:190,
        };
          
        var char1 = {
            w:15,
            h:90,
            spdX:3,
            spdY:3,
            x:10,
            y:155,
        };
          
        var char2 = {
            w:15,
            h:90,
            spdX:3,
            spdY:3,
            x:674,
            y:155,
        };
          
          // UPDATE
          
          function updateEntity(a) {
            a.x+=a.spdX;
            a.y+=a.spdY;
            ctx.clearRect(0,0,width,height);
            ctx.fillRect(a.x,a.y,a.height,a.width);
              if(a.x > width-a.width || a.x < 0) {
                a.spdX = -a.spdX;
              };
              
              if(a.y > height-a.height || a.y < 0) {
                a.spdY = -a.spdY;
              };
          };
          
          function renderChar(b) {
            ctx.fillRect(b.x,b.y,b.w,b.h);
          };
          
          function checkInput() {
            document.addEventListener('onkeydown', function(e) {
                if(e.keyCode == 37) {
                    char1.y += 1;
                }
                else if(e.keyCode == 39) {
                    char1.y -= 1;
                }
            });
          };
          
          function checkWinP1() {
              if (ball.x < 0.33) {
                console.log("P1 Wins");
              };
          };
          function checkWinP2() {
              if (ball.x > 679) {
                console.log("P2 Wins");
              };
          };
          
          function update() {
            updateEntity(ball);
            renderChar(char1);
            renderChar(char2);
            checkInput();
            checkWinP1();
            checkWinP2();
          };
          
          //TICKS
          
          setInterval(update,1000/120);


    //NEW CODE TO MANAGE THE CHARACTERS MOTION

    var characterSpeed = 15;

    $(document).on("keydown", function (e) {
        switch (e.which)
        {
            case 87: //w
                char1.y -= characterSpeed;
                break;
            case 83: //s
                char1.y += characterSpeed;
                break;
            case 38: //up arrow
                char2.y -= characterSpeed;
                break;
            case 40: //down arrow
                char2.y += characterSpeed;
                break;
            default:
                alert("You have pressed the key " + e.which);
         } 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
  <head>
      <title>Pingedy Pong</title>
  </head>
  <body style="font-family:Arial;">
      <canvas id="ctx" width="699" height="400" style="background-color:black;border:2px solid black;background-image: url('background.jpg');"></canvas>
      <script>
        

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

Also, you maybe want to read this two posts:

  • How to find out what character key is pressed?
  • Simplest way to detect keypresses in javascript

You will get to know about how to bind multiple handlers to the same event, the difference between IE and the rest of the browsers, the String.fromCharCode function and, if you are interested, how to write the same code with vanilla javascript.

Hope it helps!

like image 124
David Avatar answered Nov 14 '22 22:11

David