Here is a "hello world" simple skeleton I wrote to get started on an HTML5/javascript game. I converted it from a python example provided in Coursera's "An Introduction to Interactive Programming in Python" which demonstrates how to start moving a ball around a canvas using arrow keys.
I did this as a learning exercise to get to grips with javascript. While I've got this code to pass jslint, I was wondering if more experienced javascript coders could suggest better ways of doing this.
var canvas, context, ball_pos, vel, keys = {};
var BALL_RADIUS = 20;
function init() {
'use strict';
canvas = document.getElementById('c');
context = canvas.getContext('2d');
ball_pos = [canvas.width / 2, canvas.height / 2];
vel = 4;
}
function draw() {
'use strict';
// draw background
context.fillStyle = 'black';
context.fillRect(0, 0, canvas.width, canvas.height);
// draw ball
context.strokeStyle = 'red';
context.lineWidth = 2;
context.fillStyle = 'white';
context.beginPath();
context.arc(ball_pos[0], ball_pos[1], BALL_RADIUS, 0, Math.PI * 2, true);
context.closePath();
context.fill();
context.stroke();
}
function keydown(evt) {
'use strict';
// mozilla based browsers return which and others keyCode
var keyCode = evt.which || evt.keyCode;
keys[keyCode] = true;
// alert(keyCode)
// 33 up right
// 34 down right
// 35 down right
// 36 up left
if (keys[37]) { // left
ball_pos[0] -= vel;
}
if (keys[38]) { // up
ball_pos[1] -= vel;
}
if (keys[39]) { // right
ball_pos[0] += vel;
}
if (keys[40]) { // down
ball_pos[1] += vel;
}
}
function keyup(evt) {
'use strict';
var keyCode = evt.which || evt.keyCode;
delete keys[keyCode];
}
function animate() {
'use strict';
window.requestAnimationFrame(animate);
draw();
}
// register event handlers
window.onkeydown = keydown;
window.onkeyup = keyup;
init();
animate();
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="c" width="600" height="400"></canvas>
</body>
</html>
1 Answer 1
Instead of using ball_pos as an array with two elements to contain the x and y coordinate values of the ball,
it would be more natural to use a an object like this:
ball = {
x: canvas.width() / 2,
y: canvas.height() / 2
}
Instead of writing keys[37] and explaining with a comment // left what the number means,
it would be better to put that in a well-named variables, for example:
var KEY_LEFT = 37;
Then you can rewrite the conditions like this:
if (keys[KEY_LEFT]) {
ball.x -= vel;
}
if (keys[KEY_UP]) {
ball.y -= vel;
}
Putting it together:
var canvas, context, ball, vel, keys = {};
var BALL_RADIUS = 20;
var KEY_LEFT = 37;
var KEY_UP = 38;
var KEY_RIGHT = 39;
var KEY_DOWN = 40;
function init() {
'use strict';
canvas = document.getElementById('c');
context = canvas.getContext('2d');
ball = { x: canvas.width / 2, y: canvas.height / 2 };
vel = 4;
}
function draw() {
'use strict';
// draw background
context.fillStyle = 'black';
context.fillRect(0, 0, canvas.width, canvas.height);
// draw ball
context.strokeStyle = 'red';
context.lineWidth = 2;
context.fillStyle = 'white';
context.beginPath();
context.arc(ball.x, ball.y, BALL_RADIUS, 0, Math.PI * 2, true);
context.closePath();
context.fill();
context.stroke();
}
function keydown(evt) {
'use strict';
// mozilla based browsers return which and others keyCode
var keyCode = evt.which || evt.keyCode;
keys[keyCode] = true;
// alert(keyCode)
// 33 up right
// 34 down right
// 35 down right
// 36 up left
if (keys[KEY_LEFT]) {
ball.x -= vel;
}
if (keys[KEY_UP]) {
ball.y -= vel;
}
if (keys[KEY_RIGHT]) {
ball.x += vel;
}
if (keys[KEY_DOWN]) {
ball.y += vel;
}
}
function keyup(evt) {
'use strict';
var keyCode = evt.which || evt.keyCode;
delete keys[keyCode];
}
function animate() {
'use strict';
window.requestAnimationFrame(animate);
draw();
}
// register event handlers
window.onkeydown = keydown;
window.onkeyup = keyup;
init();
animate();
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="c" width="600" height="400"></canvas>
</body>
</html>
-
3\$\begingroup\$ I agree about using x and y instead of an array. But I'm not so sure about using switch instead of multiple ifs: a problem I hit was to allow someone to press say up and left simultaneously to move diagonally (which is why the keys object is needed to store more than one downkey at a time). That's also why I've got lots of ifs instead of if else statements. \$\endgroup\$joeblog– joeblog2014年12月11日 21:24:04 +00:00Commented Dec 11, 2014 at 21:24
-
2\$\begingroup\$ You're absolutely right! I dropped that point and fixed my post. Thanks for pointing out! \$\endgroup\$janos– janos2014年12月11日 21:34:11 +00:00Commented Dec 11, 2014 at 21:34
-
1\$\begingroup\$ Also, Instead using "use strict" in every function, create an IIFE and put it in the beginning. \$\endgroup\$Enrique Moreno Tent– Enrique Moreno Tent2014年12月12日 08:05:45 +00:00Commented Dec 12, 2014 at 8:05