Asker
Asker

Reputation: 107

I'm trying to make the canvas element move with keyboard

I know this question has been answered like a q2i3648123648 times but I'm trying to make the red square move with the keyboard for some reason the code worked with mouse event but doesn't seem to work with keyboard input this is the javascript code

let canvas;
let canvasContext;

let playerPositionX = 10;
let playerPositionY = 10;
let playerSpeed = 5;
const load = () => {
  canvas = document.getElementById("gameCanvas");
  canvasContext = canvas.getContext('2d');


  let framesPerSecond = 30;
  setInterval(() => {
    gameObjects();
  }, 1000 / framesPerSecond);
  // moving the player
  canvas.addEventListener("onkeydown", (e) => {
      if(e.keyCode === 87){
        playerPositionX += playerSpeed;
      }
  });

};
const gameObjects = () => {
  // canvas
  component(0, 0, canvas.width, canvas.height, 'black');

  // player
  component(playerPositionX, playerPositionY, 30, 30, 'red');
};

const component = (positionX, positionY, width, height, color) => {
  canvasContext.fillStyle = color;
  canvasContext.fillRect(positionX, positionY, width, height);
};



window.onload = load;

Upvotes: 0

Views: 832

Answers (1)

Blindman67
Blindman67

Reputation: 54109

KeyboardEvent.keyCode is a depreciated property. Use KeyboardEvent.code

  • Separate the keyboard event listener from the control logic.
  • Listen to both the key down and key up events and set a flag that a particular key is down.
  • In the main loop check that flag and make the movement as needed.
  • Use [requestAnimationFrame][3] to render.

Example

The example below show how to create a keyboard interface. It removes the keyboard auto repeat as a concern. You can stop the input if needed by just setting the keys.nameOfKey = false;

const ctx = canvas.getContext("2d");
const frameRate = 30;  // must divide into 60 by whole number eg 60,30,20,15,10
var frameCount = 0;

// define keys to listen to
const keys = {
    ArrowUp: false,
    ArrowDown: false,
    ArrowLeft: false,
    ArrowRight: false,
    anykey: false,
};

// sets key to true if key is down
function keyboardEvent(event) {
    if (keys[event.code] !== undefined) {
         keys[event.code] = event.type === "keydown";
         event.preventDefault();
         event.type === "keydown" && (keys.anykey = true);
    }
}

// add key listeners to window
addEventListener("keydown", keyboardEvent);
addEventListener("keyup", keyboardEvent);

// For SO snippet as it will not focus without user click.
canvas.addEventListener("click",() =>  requestAnimationFrame(update), {once: true});
ctx.font = "16px arial";
ctx.textAlign = "center";
ctx.fillText("Click to focus keyboard", canvas.width / 2, canvas.height / 2);


const player = {
    x: 0, y: 0, w: 10, h: 10, speed: 5,
    draw() {
        ctx.fillRect(player.x, player.y, player.w, player.h);
    },
    move() {
        if (keys.ArrowUp) { player.y -= player.speed }
        if (keys.ArrowDown) { player.y += player.speed }
        if (keys.ArrowRight) { player.x += player.speed }
        if (keys.ArrowLeft) { player.x -= player.speed }
        if (player.y < 0) { player.y = 0 }
        if (player.y + player.h > canvas.height ) { player.y = canvas.height - player.h }
        if (player.x + player.w > canvas.width ) { player.x = canvas.width - player.w }
        if (player.x < 0) { player.x = 0 }
    }
}

function update(){
     if (frameCount % (60 / frameRate) === 0) {
         ctx.clearRect(0,0,canvas.width, canvas.height);
         player.move();
         player.draw();
         if (!keys.anykey) {
             ctx.fillText("Arrow keys to move!", canvas.width / 2, canvas.height / 2);
         }
     }
     frameCount += 1;
     requestAnimationFrame(update);
}
canvas {
    border: 2px solid black;
}
<canvas id="canvas"></canvas>

Upvotes: 1

Related Questions