Canvas Basics – 04 Move An Object Using The Keyboard

x and y positions example for maths in games

This is the fourth part of a series of posts looking at the <canvas> element in HTML5.

I have been using the canvas element to create games and over this series of posts will look at some of the Canvas basics.

This is a follow on from the posts looking at maths in games (click here to read the first post).

If you are not already familiar with HTML, you can read through the posts starting here (click to read).

The first 3 posts in this series can be found at:

  1. Canvas Basics – 01 Hello World
  2. Canvas Basics – 02 Mouse Detection
  3. Canvas Basics – 03 Moving An Object

You can start reading the above links if you have no HTML/Javascript/Canvas experience, or if you have some of the basics covered already, you can continue with this post.

This post is going to show you how to create an object and move it using the keyboard’s arrow keys.

 

What you’ll need

For these posts you will need a text editor (Notepad on Windows for example) and a relatively up to date browser (Google Chrome is my preference).

In the screenshots you are about to see, you will see that I am not using Notepad for coding, this is because I am using a different package which allows you to see line numbers, this will make it easier for me to comment on particular lines.

 

Instructions

If you plan on following all steps in these posts, at this point I would advise setting up a folder to store all the files you will create.

In the previous posts, you had a .html file which by default will open in a web browser.

For this post you will have a .html file and also a .js file

You will be editing these files in your text editor (for example, right-click the .html file in your folder and choose to open with Notepad) and viewing the .html file in your web browser.

After each step, you might have to save the text editor file and then refresh your web browser to view the changes.

During instructions, I might tell you to save the file and refresh the browser, I will be referring to the line above.

 

Skeleton

We are going to create a new .html file and call this “skeleton2.html”.

This will be a basic file with very little in it.

empty skeleton2 file

 

The code for this bare skeleton is:

<!DOCTYPE html>
<head>
<title></title>
</head>
<body>
</body>
</html>

Save this file as “skeleton2.html”.

Now we will add to the bare file.

image of the final skeleton2.html page

  • Line 3 – Change the document title to be My Game
  • Line 6 – <canvas id=”canvas”> here we add the opening canvas tag to the body of our page.  Previously we had included the script for the canvas in the head section of the page, but we are going to save the script in a separate .js file which we will reference in line 9.
  • Line 7 – Your browser doesn’t support Canvas, try another or update This message will only be seen if the user’s browser doesn’t support Canvas and won’t know what to do with <canvas></canvas>
  • Line 8 – </canvas> this is the closing tag for our canvas elements
  • Line 9 – <script src=”game1.js”></script> unlike previous posts where the script for our canvas was entered in the head of the page, here we are making reference to a file called game1.js (which we will create soon).  Note this line also includes the closing script tag </script>.

The full code for skeleton2.html is now

<!DOCTYPE html>
<head>
<title>My Game</title>
</head>
<body>
<canvas id="canvas">
Your browser doesn't support Canvas, try another or update
</canvas>
<script src="game1.js"></script>
</body>
</html>

 

Going forward, you are going to view the “skeleton2.html” file in your browser, but all the code we are about to create will be entered in the game1.js file in your text editor.

 

game1.js

In your text editor, create a new blank file, save it to the same location/folder as your skeleton2.html file.

Name this new file “game1.js”

Remember your skeleton2.html file has said the source (src) for the canvas script can be found in game1.js.

 

 

Canvas Basics – Draw A Shape & Move It With The Keyboard

This post will draw a rectangle on screen in a slightly different way, but this time instead of it moving automatically, you are going to have it moved by the keyboard arrows.

Let’s Begin

Open the game1.js file in your text editor.

We will start building this file now and working through each section as we go.

image showing first part of game1.js file

  • LINE 1 – var canvas = document.getElementById(‘canvas’);  this may look familiar to you from prior posts.  We are identifying our canvas here (the .html file id’s our canvas as ‘canvas’ too).
  • LINE 2 – var ctx = canvas.getContext(‘2d’); as before, we are going to use the 2d context (as opposed to 3d) of the canvas
  • LINE 4 – canvas.width = window.innerWidth; in earlier posts, we set the width and height of the canvas as numeric values, here we are setting it to be the window’s width and height
  • LINE 5 – canvas.height = window.innerHeight; in earlier posts, we set the width and height of the canvas as numeric values, here we are setting it to be the window’s width and height

 

Note The Keys

The next section we will add relates to the keys.

We are going to create an array variable to store the keys pressed (an array in this case is a group of keys, not just one value like a standard variable would hold).

Then we add an eventListener, for when a key is pressed down.  This adds the key to the array of keys pressed.

When the key is released, another eventListener removes that key from the keys pressed array.

image of the keys section of game1.js

  • LINE 7 – var keys = {}; this creates an array variable called keys.
  • LINE 9 – window.addEventListener(‘keydown’, function(e){ this event listener ‘listens’ for when a key is pressed down and starts a function based on this event (e).  The function is contained within the curly brackets.
  • LINE 10 – keys[e.keyCode] = true; when a key is pressed down, this event (e) calls the function and the numeric value of the key (also called the keyCode) is stored in the keys array.  You can find the keyCode for any keyboard key by searching online, there are too many to cover in this post.
  • LINE 11 – e.preventDefault(); in this example, this is a very important line.  This is telling the browser not to act on the default action of the key pressed, that we will handle the action through code.  For example, in this case if the user pressed the down key, we will want our box to move down and not for the page to scroll down which may be the default action.
  • LINE 12 – }); This is the closing bracket for the function and event listener from line 9.
  • LINE 14 – window.addEventListener(‘keyup’, function(e){ this time we are adding an event listener for when a key that was pressed down is no longer pressed down.  When this event (e) happens, whatever we enter between the { } will be called.
  • LINE 15 – delete keys[e.keyCode]; when a key pressed is released, we want to remove that key’s keyCode from the array of keys pressed.
  • LINE 16 – }); this is the closing bracket for the function and event listener from line 14.

 

 

Create Objects

In the last section, we created an array (group of objects) called “keys” and added to event listeners, one for when a key is pressed down and one for when it is released.

So far we haven’t instructed the code to do anything other than note the keys pressed and released.  Before we can move an object we need to create one first.

In earlier posts, you created an object called myBox using “var myBox = { x:10, y:10….}”.  When creating an object in this way, you are created a single object.

What we are about to do is create constructor function.  This will create a type of object which can then be used to create many objects of that type.

For example, create a constructor function for a person and then you can create several people, or, more closely related to examples we might discuss you could create a constructor function for a paddle and then create paddles based on this function for the player and the computer – if you were creating a game like Pong.

We are now going to create a constructor function for a Box object, then we will create an object called “player” which will be of the Box object type.

When creating the Box object we will include default values (x and y positions, color, etc.).

When creating the player object, if we do not assign a different value it will use the default value from the Box object.

image of code creating our box

  • LINE 18 – function Box(options){ this starts our constructor function for an object type “Box”.  the options/values for this object will be contained within { }.
  • LINE 19 – this.x = options.x || 10; the first default value for this (Box) object will be 10 on the X axis.
  • LINE 20 – this.y = options.y || 10; the next default value will be 10 on the Y axis.
  • LINE 21 – this.width = options.width || 40; the default width will be set as 40.
  • LINE 22 – this.height = options.height || 50; the default height will be 50
  • LINE 23 – this.color = options.color || ‘#000000’; the default color of the object will be black
  • LINE 24 – this.speed = options.speed || 5; the speed value will be used to move the box when keys are pressed, the higher the value the faster the box will appear to move, but if you enter too high a value the movement won’t look as smooth.
  • LINE 25 – this.direction =options.direction || ‘right’; here I’m just setting a default direction for the box, this doesn’t mean that the direction will always be right.
  • LINE 26 – } this closing bracket ends our Box constructor function.

 

  • LINE 28 – var player = new Box({ we are now going to create an object called player and this will be an object based on our Box object type.  The values we are going to set for this object will be contained withing the closing }) brackets.
  • LINE 29 – x: 10, we are going to assign the value 10 to this x position.  This is the same as the default values set earlier, but they don’t have to be the same.
  • LINE 30 – y: 10, again, the y value of 10 is being assigned here.
  • LINE 31 – width: 50, you could probably guess by now that we are assigning a width of 50.
  • LINE 32 – height: 40, the height of our player object will be 40.
  • LINE 33 – color: ‘#44ee11’, this will be the color of our object, to be honest I haven’t checked first what the color will be, I just entered random characters between 0-9 and a-f.  If I was designing an actual game I would put more thought into the color value I’d be using.
  • LINE 34 – speed: 5 the last value we will assign will be 5 for the speed
  • LINE 35 – }); this ends our player’s object properties.

 

 

Review

It may seem like a lot of code is being thrown at you in this post, but if you step back and go through it again you will see that a lot of lines are almost duplicated between the player object and the Box constructor.

Note when to use commas and when to use semi colons, this is an important thing to note.

At this point we have created objects and event listeners for key presses (and releases), but we have not yet actually shown anything on screen.

Next we will create a function to change the x and y values of our object depending on the key pressed.

For now, note the code you should have in your game1.js file so far:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var keys = {};
window.addEventListener('keydown', function (e) {
keys[e.keyCode] = true;
e.preventDefault();
});
window.addEventListener('keyup', function (e) {
delete keys[e.keyCode];
});
function Box(options) {
this.x = options.x || 10;
this.y = options.y || 10;
this.width = options.width || 40;
this.height = options.height || 50;
this.color = options.color || '#000000'
this.speed = options.speed || 5;
this.direction = options.direction || 'right';
}
var player = new Box({
X: 10,
y: 10,
width: 50,
height: 50,
color: '#44ee11',
speed: 5
});

 

 

The Input Function

We will create another function called input which will act based on the keyboard input.

The keys variable notes the keys being pressed, we are interested in the arrow keys (key codes are 37 to 40) and if the key is in our array variable, we will change the player’s x and y variables accordingly.

We are also going to change the direction property of our variable to match the new direction.

image of input function

 

  • LINE 37 – function input(player){ we create a new function called input and the argument for this function in the player variable.  You don’t always have to reference an argument/parameter, as you have seen in earlier functions the brackets can be empty.
  • LINE 38 – if(37 in keys){ the function is checking to see if 37 (left arrow) has been pressed, and if it has the actions contained within the curly brackets { } are to be completed.
  • LINE 39 – player.x -=player.speed; this reduces the current x position of player by the value of speed set earlier (5).  This may sometimes be seen as something like “player.x = player.x-player.speed;”.  This effectively moves the player object to the left.
  • LINE 40 – player.direction = ‘left’; we change the direction value of player “left” here
  • LINE 41 – } this is the closing bracket for the actions to complete if the left arrow key is being pressed.
  • LINES 42-54 the remaining lines in this function repeat the above but for the right, up and down arrow keys.

Now that we have the instructions in place for what to do when keys are pressed we now need to draw the player and loop updates to make the player box look animated.

 

 

Final Touches

We will now create functions to draw our canvas, player and update based on the keys pressed.

 

Image of last functions in this canvas basics tutorial

  • LINE 56 – function drawBox(box){ the first function will be called drawBox and will draw a rectangle with the values on the next two lines
  • LINE 57 – ctx.fillStyle = box.color; this sets the fill color of our box
  • LINE 58 – ctx.fillRect(box.x, box.y, box.width, box.height); this sets the x, y, width and height values of our drawBox object
  • LINE 59 – } this is the closing bracket for the drawBox function.

 

  • LINE 61 – function update(){ this is our update function which for now will call the input function created earlier, which takes the user’s keyboard input.
  • LINE 62 – input(player); this calls the input function for our player.
  • LINE 63 – } this is the losing bracket for the update function.

 

  • LINE 65 – function draw(){ This draw function will clear our screen before each frame and then call the drawBox function to redraw our player.
  • LINE 66- ctx.clearRect(0, 0, canvas.width, canvas.height); This clears the rectangle that is basically our whole canvas.  If you miss this step, the code will continue to draw your player on screen without clearing old frames so it looks like your player is getting longer or taller, rather than moving. (see the first post in this series to refresh if needed).
  • LINE 67 – drawBox(player); after clearing the canvas we want to redraw our player by calling the drawBox function.  This will draw the player in the new x and y positions, if it has moved.
  • LINE 68 – } this ends our draw function.

 

  • LINE 71 – function loop() { we are going to create a loop function now which will run several times per second and call other functions to animate our screen
  • LINE 72 – update(); this calls the update function which, if you checked back updated the player’s x and y positions after arrow keys were used
  • LINE 73 – draw(); this calls the draw function which clears old information from the canvas and redraws our player in its current position.
  • LINE 74 – window.requestAnimationFrame(loop); this line is very important for our animation.  We are telling our browser that we want to execute some code (the loop function) at the next screen update, this could be 60 times per second, it can depend on the user’s system and what they are running at the same time.  So in this case, we want the browser to run the loop function several times a second and this calls the update and draw functions, this is what gives the appearance of animation on the user’s screen then.
  • LINE 75 – } this closes the loop function

 

  • LINE 77 – loop(); when your browser loads the page and references you game1.js file, this line calls the loop function.  That loop function then calls the update and draw functions and because of line 74, it repeats over and over.  Without line 77, at no point in our code have we started any functions.  We may have functions that call other functions, but we haven’t actually called or started any, this is what line 77 is doing to get things started.

 

 

Review

Save your .js file.

Open the .html file in your browser and you should be able to move a green box around the screen using the arrow keys.

If it isn’t working, check your code against the code below.

If it is working, you may notice that you are able to move your shape off screen, this is because you have not set any boundaries, the shape does not know that it cannot go outside the canvas area, and this is a good time to leave this post as it is, and pick up this topic in the next post.

image showing box going off screen

 

Final .html file

<!DOCTYPE html>
<head>
<title>My Game</title>
</head>
<body>
<canvas id="canvas">
Your browser doesn't support Canvas, try another or update
</canvas>
<script src="game1.js"></script>
</body>
</html>

 

Final game1.js file

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var keys = {};
window.addEventListener('keydown', function (e) {
keys[e.keyCode] = true;
e.preventDefault();
});
window.addEventListener('keyup', function (e) {
delete keys[e.keyCode];
});
function Box(options) {
this.x = options.x || 10;
this.y = options.y || 10;
this.width = options.width || 40;
this.height = options.height || 50;
this.color = options.color || '#000000'
this.speed = options.speed || 5;
this.direction = options.direction || 'right';
}
var player = new Box({
X: 10,
y: 10,
width: 50,
height: 50,
color: '#44ee11',
speed: 5
});
function input(player) {
if (37 in keys) {
player.x -= player.speed;
player.direction = 'left';
}
if (39 in keys) {
player.x += player.speed;
player.direction = 'right';
}
if (38 in keys) {
player.y -= player.speed;
player.direction = 'up';
}
if (40 in keys) {
player.y += player.speed;
player.direction = 'down';
}
}
function drawBox(box) {
ctx.fillStyle = box.color;
ctx.fillRect(box.x, box.y, box.width, box.height);
}
function update() {
input(player);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBox(player);
}
 
function loop() {
update();
draw();
window.requestAnimationFrame(loop);
}
loop();

 

Disclaimer

I am not claiming that the code that I use in these examples is the best, most efficient and up to date code.  

Code gets updated and improved over time, what is best practice today may not be tomorrow.

email

Comments are closed

Follow

Get every new post delivered to your Inbox

Join other followers:

%d bloggers like this: