As you probably know, sometimes it can be more appropriate to use the keyboard
for input. If you are a PC gamer then your fingers probably feel comfortable
over the WASD keys. It is pretty straightforward to get input from the keyboard.
However, you can get into a tricky situation when you are holding down several
keys at the same time. In order to detect keys you will set up an event listener
on the window. It will look something similar to:
window.addEventListener("keypress", function(e) { console.log(e.key); });
Try pasting that line into the console. Now click back to the webpage and hit
some letters. You will notice that they show up in the console.
In this next example we are going to see the canvas tool fillText. This can be
used to write letters to the canvas. As you will see, you can change the size
and font with ctx.font.
<!DOCTYPE HTML>
<html>
<head>
<title>Keyboard Input</title>
</head>
<body style="margin:0px; overflow:hidden;">
<canvas id="canvas"></canvas>
<script>
var can = document.getElementById("canvas");
var ctx = can.getContext('2d');
var cw = can.width = window.innerWidth;
var ch = can.height = window.innerHeight;
window.addEventListener("keypress", function(e) { write(e); });
function write(event) {
ctx.font="70px Courier";
clear();
ctx.fillStyle = "lime";
ctx.fillText(event.key, cw/2-30, ch/2+30);
}
clear();
function clear() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, cw, ch);
}
</script>
</body>
</html>
So the keypress event is great for detecting if letters are being pressed, but have you tried pressing the arrow keys? Nothing happens! To detect arrow keys you will want to listen for the keydown and keyup events. Another problem with keypress is that if you hold down one key and then press another then it will not recognize your are still holding the first key. This is that tricky situation I mentioned up above. Our goal should be to know when any key is being pressed until it is released. This way we could do something like move a character or object on the screen and be able to move and jump at the same time.
A solution is to create an array of all the keys (their numeric keyCodes to keep it simple) that are currently down. Arrays are variables that contain several values. To make an array you will assign a variable to values (or empty) surrounded by solid brackets.
Once again, if you are unclear about arrays, please visit w3schools since they have great tutorials. There are four methods that we will need to operate on our array.
It can be very helpful to play around with these commands in the JavaScript Console in order to get a
better understanding of how they work. One feature that is very helpful is when you make an array,
once you type its name followed by a period then all the methods (kind of like tools it comes with)
are shown to you. This ability to explore objects and their methods is one of the reasons why
JavaScript is so nice to work with.
This next example is going to use an array called "keys" to keep track of which keys are currently
pressed down. This is accomplished by pushing the keyCode when the "keyup" event is detected and
splicing the keyCode when the "keydown" event is detected. Before we add or remove to the array
we check the array with an if statement so we avoid any errors like duplicate keyCodes in the array.
Now lets move a square around the screen with the arrow keys. First we will need to track the
position, this is easy to do with an object that has x and y properties. The next part is a little
bit tricky, we need to constantly check to see what keys are down so we can apply movement. We do
with animate(). Inside animate we can check to see if the keyCodes we care about are inside
the keys array and apply movement if they are. Finally we will call draw() each frame so that the
canvas will be cleared and the square will be updated.
<!DOCTYPE HTML>
<html>
<head>
<title>Keyboard Input</title>
</head>
<body style="margin:0px; overflow:hidden;" onload="animate()">
<canvas id="canvas"></canvas>
<script>
var can = document.getElementById("canvas");
var ctx = can.getContext('2d');
var cw = can.width = window.innerWidth;
var ch = can.height = window.innerHeight;
var keys = [];
var box = {x:cw/2, y:ch/2};
window.addEventListener("keydown", function(e) {
if ( keys.indexOf(e.keyCode) == -1) keys.push(e.keyCode)
});
window.addEventListener("keyup", function(e) {
var index = keys.indexOf(e.keyCode);
if (index > -1) keys.splice(index,1)
});
function animate() {
window.requestAnimationFrame(animate);
if (keys.indexOf(38) >= 0) box.y -= 1;
if (keys.indexOf(40) >= 0) box.y += 1;
if (keys.indexOf(37) >= 0) box.x -= 1;
if (keys.indexOf(39) >= 0) box.x += 1;
draw();
}
function draw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, cw, ch);
ctx.fillStyle = "yellow";
ctx.fillRect(box.x, box.y, 10, 10);
}
</script>
</body>
</html>
Hopefully you are starting to see how you might be able to turn this code into some type of game.
We will talk about functions in the next section.