6
\$\begingroup\$

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>

\$\endgroup\$
4
\$\begingroup\$

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>

| improve this answer | |
\$\endgroup\$
  • 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 Dec 11 '14 at 21:24
  • 2
    \$\begingroup\$ You're absolutely right! I dropped that point and fixed my post. Thanks for pointing out! \$\endgroup\$ – janos Dec 11 '14 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 Dec 12 '14 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.