Try Tuts+ Premium, Get Cash Back!
Build your First Game with HTML5

Build your First Game with HTML5

Tutorial Details
  • Technologies Used: HTML5, JS, CSS
  • Difficulty: Intermediate
  • Estimated Completion Time: 45-60 minutes

Final Product What You'll Be Creating

HTML5 is growing up faster than anyone could have imagined. Powerful and professional solutions are already being developed…even in the gaming world! Today, you’ll make your first game using Box2D and HTML5′s canvas tag.


What is Box2D?

Box2D is an open source and popular engine that simulates 2D physics for making games and applications. Primarily written in C++, it has been converted to numerous languages by community contributors.

With the same methods and objects, you have the ability to make your games’ physics in many languages, such as Objective C (iPhone/iPad), Actionscript 3.0 (Web), HTML 5 (Web), etc.


Step 1 - Setting up your Project

To begin developing your demo, download the Box2D engine for HTML5 here. Next, create a new HTML file with the following structure (copy js and lib directories from box2d-js project to your game folder).

Now, you must insert the necessary files to run box2D into your HTML file:

<!--[if IE]><script src="lib/excanvas.js"></script><![endif]-->
 <script src="lib/prototype-1.6.0.2.js"></script>
<!-- box2djs -->
 <script src='js/box2d/common/b2Settings.js'></script>
 <script src='js/box2d/common/math/b2Vec2.js'></script>
 <script src='js/box2d/common/math/b2Mat22.js'></script>
 <script src='js/box2d/common/math/b2Math.js'></script>
 <script src='js/box2d/collision/b2AABB.js'></script>
 <script src='js/box2d/collision/b2Bound.js'></script>
 <script src='js/box2d/collision/b2BoundValues.js'></script>
 <script src='js/box2d/collision/b2Pair.js'></script>
 <script src='js/box2d/collision/b2PairCallback.js'></script>
 <script src='js/box2d/collision/b2BufferedPair.js'></script>
 <script src='js/box2d/collision/b2PairManager.js'></script>
 <script src='js/box2d/collision/b2BroadPhase.js'></script>
 <script src='js/box2d/collision/b2Collision.js'></script>
 <script src='js/box2d/collision/Features.js'></script>
 <script src='js/box2d/collision/b2ContactID.js'></script>
 <script src='js/box2d/collision/b2ContactPoint.js'></script>
 <script src='js/box2d/collision/b2Distance.js'></script>
 <script src='js/box2d/collision/b2Manifold.js'></script>
 <script src='js/box2d/collision/b2OBB.js'></script>
 <script src='js/box2d/collision/b2Proxy.js'></script>
 <script src='js/box2d/collision/ClipVertex.js'></script>
 <script src='js/box2d/collision/shapes/b2Shape.js'></script>
 <script src='js/box2d/collision/shapes/b2ShapeDef.js'></script>
 <script src='js/box2d/collision/shapes/b2BoxDef.js'></script>
 <script src='js/box2d/collision/shapes/b2CircleDef.js'></script>
 <script src='js/box2d/collision/shapes/b2CircleShape.js'></script>
 <script src='js/box2d/collision/shapes/b2MassData.js'></script>
 <script src='js/box2d/collision/shapes/b2PolyDef.js'></script>
 <script src='js/box2d/collision/shapes/b2PolyShape.js'></script>
 <script src='js/box2d/dynamics/b2Body.js'></script>
 <script src='js/box2d/dynamics/b2BodyDef.js'></script>
 <script src='js/box2d/dynamics/b2CollisionFilter.js'></script>
 <script src='js/box2d/dynamics/b2Island.js'></script>
 <script src='js/box2d/dynamics/b2TimeStep.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactNode.js'></script>
 <script src='js/box2d/dynamics/contacts/b2Contact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactConstraint.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactConstraintPoint.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactRegister.js'></script>
 <script src='js/box2d/dynamics/contacts/b2ContactSolver.js'></script>
 <script src='js/box2d/dynamics/contacts/b2CircleContact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2Conservative.js'></script>
 <script src='js/box2d/dynamics/contacts/b2NullContact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2PolyAndCircleContact.js'></script>
 <script src='js/box2d/dynamics/contacts/b2PolyContact.js'></script>
 <script src='js/box2d/dynamics/b2ContactManager.js'></script>
 <script src='js/box2d/dynamics/b2World.js'></script>
 <script src='js/box2d/dynamics/b2WorldListener.js'></script>
 <script src='js/box2d/dynamics/joints/b2JointNode.js'></script>
 <script src='js/box2d/dynamics/joints/b2Joint.js'></script>
 <script src='js/box2d/dynamics/joints/b2JointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2DistanceJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2DistanceJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2Jacobian.js'></script>
 <script src='js/box2d/dynamics/joints/b2GearJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2GearJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2MouseJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2MouseJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2PrismaticJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2PrismaticJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2PulleyJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2PulleyJointDef.js'></script>
 <script src='js/box2d/dynamics/joints/b2RevoluteJoint.js'></script>
 <script src='js/box2d/dynamics/joints/b2RevoluteJointDef.js'></script>

Yep, that’s a huge number of HTTP requests!

Please note that, for deployment, it’s highly recommended that you concatenate all of these resources into one script file.

Next, create two more scripts inside the /js/ folder, called "box2dutils.js" and "game.js".

  • box2dutils.js – it’s a copy and paste from some demos that come with box2dlib, and is important for drawing functions (I will also explain some important parts here).
  • game.js – the game, itself; this is where we create the platforms, the player, apply the keyboard interactions, etc.

Copy and paste the following code into box2dutils.js. Don’t worry! I’ll explain it bit by bit!


function drawWorld(world, context) {
	for (var j = world.m_jointList; j; j = j.m_next) {
		drawJoint(j, context);
	}
	for (var b = world.m_bodyList; b; b = b.m_next) {
		for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
			drawShape(s, context);
		}
	}
}
function drawJoint(joint, context) {
	var b1 = joint.m_body1;
	var b2 = joint.m_body2;
	var x1 = b1.m_position;
	var x2 = b2.m_position;
	var p1 = joint.GetAnchor1();
	var p2 = joint.GetAnchor2();
	context.strokeStyle = '#00eeee';
	context.beginPath();
	switch (joint.m_type) {
	case b2Joint.e_distanceJoint:
		context.moveTo(p1.x, p1.y);
		context.lineTo(p2.x, p2.y);
		break;

	case b2Joint.e_pulleyJoint:
		// TODO
		break;

	default:
		if (b1 == world.m_groundBody) {
			context.moveTo(p1.x, p1.y);
			context.lineTo(x2.x, x2.y);
		}
		else if (b2 == world.m_groundBody) {
			context.moveTo(p1.x, p1.y);
			context.lineTo(x1.x, x1.y);
		}
		else {
			context.moveTo(x1.x, x1.y);
			context.lineTo(p1.x, p1.y);
			context.lineTo(x2.x, x2.y);
			context.lineTo(p2.x, p2.y);
		}
		break;
	}
	context.stroke();
}
function drawShape(shape, context) {
	context.strokeStyle = '#000000';
	context.beginPath();
	switch (shape.m_type) {
	case b2Shape.e_circleShape:
		{
			var circle = shape;
			var pos = circle.m_position;
			var r = circle.m_radius;
			var segments = 16.0;
			var theta = 0.0;
			var dtheta = 2.0 * Math.PI / segments;
			// draw circle
			context.moveTo(pos.x + r, pos.y);
			for (var i = 0; i < segments; i++) {
				var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
				var v = b2Math.AddVV(pos, d);
				context.lineTo(v.x, v.y);
				theta += dtheta;
			}
			context.lineTo(pos.x + r, pos.y);
	
			// draw radius
			context.moveTo(pos.x, pos.y);
			var ax = circle.m_R.col1;
			var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
			context.lineTo(pos2.x, pos2.y);
		}
		break;
	case b2Shape.e_polyShape:
		{
			var poly = shape;
			var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
			context.moveTo(tV.x, tV.y);
			for (var i = 0; i < poly.m_vertexCount; i++) {
				var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
				context.lineTo(v.x, v.y);
			}
			context.lineTo(tV.x, tV.y);
		}
		break;
	}
	context.stroke();
}
function createWorld() {
	var worldAABB = new b2AABB();
	worldAABB.minVertex.Set(-1000, -1000);
	worldAABB.maxVertex.Set(1000, 1000);
	var gravity = new b2Vec2(0, 300);
	var doSleep = true;
	var world = new b2World(worldAABB, gravity, doSleep);
	return world;
}

function createGround(world) {
	var groundSd = new b2BoxDef();
	groundSd.extents.Set(1000, 50);
	groundSd.restitution = 0.2;
	var groundBd = new b2BodyDef();
	groundBd.AddShape(groundSd);
	groundBd.position.Set(-500, 340);
	return world.CreateBody(groundBd)
}

function createBall(world, x, y) {
	var ballSd = new b2CircleDef();
	ballSd.density = 1.0;
	ballSd.radius = 20;
	ballSd.restitution = 1.0;
	ballSd.friction = 0;
	var ballBd = new b2BodyDef();
	ballBd.AddShape(ballSd);
	ballBd.position.Set(x,y);
	return world.CreateBody(ballBd);
}

function createBox(world, x, y, width, height, fixed, userData) {
	if (typeof(fixed) == 'undefined') fixed = true;
	var boxSd = new b2BoxDef();
	if (!fixed) boxSd.density = 1.0;
	
	boxSd.userData = userData;
	
	boxSd.extents.Set(width, height);
	var boxBd = new b2BodyDef();
	boxBd.AddShape(boxSd);
	boxBd.position.Set(x,y);
	return world.CreateBody(boxBd)
}

Step 2 - Developing the Game

Open the index.html file that you previously created, and add a canvas element (600x400) within the body element. This is where we'll work with the HTML5 drawing API:


Also, while you're here, reference game.js and box2dutils.js.

<script src='js/box2dutils.js'></script> 
<script src='js/game.js'></script>

That'll do it for the HTML! Let's work on the fun JavaScript now!

Open game.js, and insert the code below:

// some variables that we gonna use in this demo
var initId = 0;
var player = function(){
	this.object = null;
	this.canJump = false;
};
var world;
var ctx;
var canvasWidth;
var canvasHeight;
var keys = [];

// HTML5 onLoad event
Event.observe(window, 'load', function() {
	world = createWorld(); // box2DWorld 
	ctx = $('game').getContext('2d'); // 2
	var canvasElm = $('game');
	canvasWidth = parseInt(canvasElm.width);
	canvasHeight = parseInt(canvasElm.height);
	initGame(); // 3
	step(); // 4
	
// 5
	window.addEventListener('keydown',handleKeyDown,true); 
	window.addEventListener('keyup',handleKeyUp,true);
});


Box2DWorld - that's why we're here

Okay, let's figure out what this chunk of code does!

Box2DWorld is one of the classes that is made available, via the core of box2d. Its function is simple: combine everything into one class. In box2DWorld, you have the bodies definition and collisions manager of your game or application.

Keep the game.js and box2dutils.js files open, and search for the createWorld() function within box2dutils.js.

function createWorld() {
	// here we create our world settings for collisions
	var worldAABB = new b2AABB();
	worldAABB.minVertex.Set(-1000, -1000);
	worldAABB.maxVertex.Set(1000, 1000);
	// set gravity vector
	var gravity = new b2Vec2(0, 300);
	var doSleep = true;
	// init our world and return its value
	var world = new b2World(worldAABB, gravity, doSleep);
	return world;
}

It's quite simple to create the box2DWorld.


Back to game.js

Refer to the commented numbers in the two blocks of code above. On number two, we retrieve the canvas element's context by using the selector API (looks like jQuery or MooTools selectors, don't they?). On number three, we have a new interesting function: initGame(). This is where we create the scenery.

Copy and paste the code below into game.js, and then we'll review it together.

function initGame(){
	// create 2 big platforms	
	createBox(world, 3, 230, 60, 180, true, 'ground');
	createBox(world, 560, 360, 50, 50, true, 'ground');
	
	// create small platforms
	for (var i = 0; i < 5; i++){
		createBox(world, 150+(80*i), 360, 5, 40+(i*15), true, 'ground');	
	}
	
	// create player ball
	var ballSd = new b2CircleDef();
	ballSd.density = 0.1;
	ballSd.radius = 12;
	ballSd.restitution = 0.5;
	ballSd.friction = 1;
	ballSd.userData = 'player';
	var ballBd = new b2BodyDef();
	ballBd.linearDamping = .03;
	ballBd.allowSleep = false;
	ballBd.AddShape(ballSd);
	ballBd.position.Set(20,0);
	player.object = world.CreateBody(ballBd);
	
}

Inside box2dutils.js, we've created a function, called createBox. This creates a static rectangle body.

function createBox(world, x, y, width, height, fixed, userData) { if (typeof(fixed) == 'undefined') fixed = true; //1 var boxSd = new b2BoxDef(); if (!fixed) boxSd.density = 1.0; //2 boxSd.userData = userData; //3 boxSd.extents.Set(width, height); //4 var boxBd = new b2BodyDef(); boxBd.AddShape(boxSd); //5 boxBd.position.Set(x,y); //6 return world.CreateBody(boxBd) }

Box2DBody

A Box2DBody has some unique characteristics:

  • It can be static (not affected by collisions impacts), kinematic (it isn't affected by collisions, but it can be moved by your mouse, for example), or dynamic (interacts with everything)
  • Must have a shape definition, and should indicate how the object appears
  • May have more than one fixture, which indicates how the object will interact with collisions
  • Its position is set by the center of your object, not the left top edge as many other engines do.

Reviewing the code:

  1. Here, we create one shape definition that will be a square or rectangle, and setup its density (how often it gonna be moved, or rotate by forces).
  2. We setup the userData, usually you setup graphics objects here, but in this example, I just setup strings that will be the identifier of the type of the object for collisions. This parameter doesn't affect physics algorithms.
  3. Setup half of the size of my box (it's a line from the position point, or the center point of the object to a corner)
  4. We create the body definition, and add to it the box shape definition.
  5. Setup the position.
  6. Create the body in the world and return its value.

Creating the Player Ball Body

I've coded the player (ball) directly in the game.js file. It follows the same sequence of creating boxes, but, this time, it's a ball.

var ballSd = new b2CircleDef();
	ballSd.density = 0.1;
	ballSd.radius = 12;
	ballSd.restitution = 0.5;
	ballSd.friction = 1;
	ballSd.userData = 'player';
	var ballBd = new b2BodyDef();
	ballBd.linearDamping = .03;
	ballBd.allowSleep = false;
	ballBd.AddShape(ballSd);
	ballBd.position.Set(20,0);
	player.object = world.CreateBody(ballBd);

So how do we create a body, step by step?

  1. Create the shape, fixture and sensor definition
  2. Create the body definition
  3. Add into the body your shape, fixtures or sensors (not explained in this article)
  4. Create the body in the world

Box2DCircle

As I noted earlier, this follows the same creation process of a box, but now you must set some new parameters.

  • radius - This is the length of a line from the center of the circle to any point on its edge.
  • restitution - How the ball will lose, or gain force when collides with other body.
  • friction - How the ball will roll.

Box2DBody - More Properties

  • damping is used to reduce the velocity of the body - there's angular damping and linear damping.
  • sleep in box2D, bodies can sleep to solve performance issues. For example, let's suppose you are developing a platform game, and the level is defined by a 6000x400 screen. Why do you need to perform physics for objects that are off screen? You don't; that's the point! So the correct choice is to put them to sleep, and improve your game's performance.

We've already created our world; you can test the code that you have so far. You'll see the player falling above the west platform.

Now, if you tried to run the demo, you should be wondering, why is the page as barren as white paper?

Always remember: Box2D doesn't render; it only calculates physics.


Step 3 - Rendering Time

Next, let's render the box2DWorld.

Open your game.js script, and add the following code:

function step() {
	
	var stepping = false;
	var timeStep = 1.0/60;
	var iteration = 1;
	// 1
	world.Step(timeStep, iteration);
	// 2
	ctx.clearRect(0, 0, canvasWidth, canvasHeight);
	drawWorld(world, ctx);
	// 3
	setTimeout('step()', 10);
}

What we accomplish here:

  1. Instructed box2dWorld to perform physics simulations
  2. Cleared canvas screen and draw again
  3. Execute the step() function again in ten milliseconds

With this bit of code, we are now working with physics and drawing. You can test yourself, and watch for a falling ball, as demonstrated below:


drawWorld in box2dutils.js

function drawWorld(world, context) {
	for (var j = world.m_jointList; j; j = j.m_next) {
		drawJoint(j, context);
	}
	for (var b = world.m_bodyList; b; b = b.m_next) {
		for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
			drawShape(s, context);
		}
	}
}

What we've written above is a debug function that draws our world into the canvas, using the graphics API provided by HTML5's Canvas API.

The first loop draws all joints. We didn't use joints in this article. They are a bit complex for a first demo, but, nonetheless, they're essential for your games. They allow you to create very interesting bodies.

The second loop draws all bodies, which is why we're here!

function drawShape(shape, context) {
	context.strokeStyle = '#000000';
	context.beginPath();
	switch (shape.m_type) {
	case b2Shape.e_circleShape:
		{
			var circle = shape;
			var pos = circle.m_position;
			var r = circle.m_radius;
			var segments = 16.0;
			var theta = 0.0;
			var dtheta = 2.0 * Math.PI / segments;
			// draw circle
			context.moveTo(pos.x + r, pos.y);
			for (var i = 0; i < segments; i++) {
				var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
				var v = b2Math.AddVV(pos, d);
				context.lineTo(v.x, v.y);
				theta += dtheta;
			}
			context.lineTo(pos.x + r, pos.y);
	
			// draw radius
			context.moveTo(pos.x, pos.y);
			var ax = circle.m_R.col1;
			var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
			context.lineTo(pos2.x, pos2.y);
		}
		break;
	case b2Shape.e_polyShape:
		{
			var poly = shape;
			var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
			context.moveTo(tV.x, tV.y);
			for (var i = 0; i < poly.m_vertexCount; i++) {
				var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
				context.lineTo(v.x, v.y);
			}
			context.lineTo(tV.x, tV.y);
		}
		break;
	}
	context.stroke();
}

We're looping through every vertices of the object and drawing it with lines (context.moveTo and context.lineTo). Now, it's useful to have an example... but not so useful in practice. When you use graphics, you only need to pay attention to the bodies' positioning. You don't need to loop vertices, as this demo does.


Step 4 - Interactivity

A game without interactivity is a movie, and a movie with interactivity is a game.

Let's develop the keyboard arrow functionality to jump and move the ball.

Add the following code to your game.js file:

function handleKeyDown(evt){
	keys[evt.keyCode] = true;
}
function handleKeyUp(evt){
	keys[evt.keyCode] = false;
}

// disable vertical scrolling from arrows :)
document.onkeydown=function(){return event.keyCode!=38 && event.keyCode!=40}

With handleKeyDown and handleKeyUp, we setup an array which tracks every key the user types. With document.onkeydown, we disable the browser's native vertical scrolling function for up and down arrows. Have you ever played an HTML5 game, and when you jump, the player, enemies and objects go off screen? That won't be an issue now.

Add this next bit of code to the beginning of your step() function:

handleInteractions();

And outside, declare the function:

function handleInteractions(){
	// up arrow
	// 1
	var collision = world.m_contactList;
	player.canJump = false;
	if (collision != null){
		if (collision.GetShape1().GetUserData() == 'player' || collision.GetShape2().GetUserData() == 'player'){
			if ((collision.GetShape1().GetUserData() == 'ground' || collision.GetShape2().GetUserData() == 'ground')){
				var playerObj = (collision.GetShape1().GetUserData() == 'player' ? collision.GetShape1().GetPosition() :  collision.GetShape2().GetPosition());
				var groundObj = (collision.GetShape1().GetUserData() == 'ground' ? collision.GetShape1().GetPosition() :  collision.GetShape2().GetPosition());
				if (playerObj.y < groundObj.y){
					player.canJump = true;
				}
			}
		}
	}
	// 2
	var vel = player.object.GetLinearVelocity();
	// 3
	if (keys[38] && player.canJump){
		vel.y = -150;	
	}
	
	// 4
	// left/right arrows
	if (keys[37]){
		vel.x = -60;
	}
	else if (keys[39]){
		vel.x = 60;
	}
	
	// 5
	player.object.SetLinearVelocity(vel);
}

The most complicated piece of the code above is the first one, where we check for a collision, and write some conditions to determine if the shape1 or the shape2 is the player. If it is, we verify if shape1 or shape2 is a ground object. Again, if so, the player is colliding with the ground. Next, we check if the player is above the ground. If that's the case, then the player can jump.

On the second commented line (2), we retrieve the LinearVelocity of the player.

The third and forth commented regions verify if arrows are being pressed, and adjust the velocity vector, accordingly.

In the fifth region, we setup the player with the new velocity vector.

The interactions are now done! But there's no objective, We just jump, jump, jump… and jump!


Step 5 - "You Win" Message

Add the code below to the beginning of your LinearVelocity function:

	if (player.object.GetCenterPosition().y > canvasHeight){
		player.object.SetCenterPosition(new b2Vec2(20,0),0)
	}	
	else if (player.object.GetCenterPosition().x > canvasWidth-50){
		showWin();
		return;	
	}
  • The first condition determines if the player falls, and should be transported back to the start point (above the west platform).
  • The second condition checks if the player is above the second platform, and won the game. Here's the showWin() function.
function showWin(){
	ctx.fillStyle    = '#000';
	ctx.font         = '30px verdana';
	ctx.textBaseline = 'top';
	ctx.fillText('Ye! you made it!', 30, 0);
	ctx.fillText('thank you, andersonferminiano.com', 30, 30);
	ctx.fillText('@andferminiano', 30, 60);	
}

And that's it! You've just completed your first simple game with HTML5 and Box2D. Congratulations!

Tags: html5
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.appmobi.com Roy Smith

    Great tutorial! Just wanted to point out that if you want to take your game into the app stores, there are ways to take HTML5 games and build them into native apps for iOS and Android. That’s what we do at appMobi.

  • Gediminas

    There is a jQuery error:
    event is not defined
    document.onkeydown=function(){return event.keyCode!=38 && event.keyCode!=40}
    http://andersonferminiano.com/html5/studies/Box2DAdventureGame/js/game.js
    Line 142

    • James

      @Gediminas I don’t think the demo even uses jQuery…

  • imad

    First :)

  • http://rommelcastro.me Rommel Castro A.

    this is so great (:

  • Colin

    In Firebug, I see this error on every keypress. Over the course of the game, holding down arrow keys chaulked up 545 errors.

    event is not defined
    game.js (line 142)
    document.onkeydown=function(){return event.keyCode!=38 && event.keyCode!=40}

    • http://briganti.autodepan.ro/ Csongor

      Change this line:

      document.onkeydown=function(){return event.keyCode!=38 && event.keyCode!=40}

      to

      document.onkeydown=function(event){return event.keyCode!=38 && event.keyCode!=40}

      Bye :)

  • Gabriel

    Lol, how fun is that, huh?

  • http://www.zaczac-zarabiac.pl/ Robert

    Hi,

    Great tutorial! Something different :)

  • Andrew Smith

    Could you perhaps provide a minified js file with all the Box2d stuff?

    Thanks!

  • Bhaarat

    Very interesting and unique.

    You’ve forgotten to close some tags in the article though which is messing up the fonts.

    Plan to make a game based on this article soon.

  • http://bit.ly/cLZXGi Julian

    Very Cool! Going to try this over the weekend.

  • http://inspirationfeed.com inspirationfeed

    This would be a neat side project for me!

  • http://www.jeffadams.co.uk Jeff Adams

    Most random yet unique totorial yet!!!

  • http://www.vankoder.com Don Burks

    While definitely good to demonstrate all of the architecture to make this game work, there is a lot of easy optimization that could be done on this code that would not only benefit the performance, but also instill readers with good coding practices.

    One example I will offer up is combining var statements in JS.

    Instead of doing:

    var first_var = “some value”;
    var second_var = “some other value”;
    var third_var = “yet more value”;

    it would be much better to do:

    var first_var = “some value”,
    second_var = “some other value”,
    third_var = “yet more value”;

    Overall, though, I love this tutorial.

  • Leo

    Or you can use Gamesalad :D http://www.gamesalad.com

    • http://www.symetronapps.com luka

      CODING!!! not the cheap way

  • Abhijit

    The perfect tutorial for next weekend. Tried the demo, but could not go past the first pillar… Will try to make an easier version for myself :)

    • Abhijit

      By the way, the demo always has lags in FF5, but runs smooth on Chrome and does not work in IE9. Way to go for browsers?

      • Ramul

        Well, It surely wouln’t work on IE6!! lol

  • http://www.mufid.net Muifd

    Very cool! Thanks! Btw, it would be nice if there’s also video version :)

  • Bugster

    Great tutorial!

    By the way there’s a typo in the section “Back to game.js” on line 27 of the code block

  • Meme

    This is blasphemy!

  • http://google.com Jon

    very cool!

  • http://www.футболмастер.рф/ alex

    Thats awesome. Now i can make my own browser game on html5. great

  • http://www.stevejonescreative.com Steve

    I can’t believe how way more complex it is to do this with HTML5 rather than Flash. I know everyone hates Flash these days but it sure made game development a lot easier. But great tut!

  • http://www.wynajembusownowysacz.pl/ gcd

    Great idea, but absence enough descriptions.
    Waiting for more

  • frank

    good for nothing..i know it is awesome and working but the way you explained is not good…those who are ‘going to copy it ,it will be good for them but people who want to play with the code won’t be able to do anything because it;s hard to understand what function does what??

    • Mark Sinkinson

      Agreed, not very impressed with the explanation given in the tutorial

  • Jane

    I’m sorry, I just don’t get it. Went to the Demo page and all that happened was that the ball bounced once. Then, even with a few mouse clicks ……… nothing. So all I got was effectively a static image.

    • Rob

      Use your arrow keys… Have you never played a game before?

  • http://www.oldworldcreative.com Evan Skuthorpe

    very cool.

  • http://www.interlacelab.com Noel

    Great tuts as always. HTML5 is the future.

  • http://www.derby-webdesign.co.uk derbywebdesign

    Wow that’s alot of JS, but very impressive at the same time. Well done =)

  • http://punkscum.org julien

    nice tutorial thanks ! a pitty the game is so hard to play

  • http://www.3rddesign.com 3rddesign

    This is a very awesome tutorial. Can’t wait to try this weekend for fun.

  • http://www.webdogs.be webdogs

    Is it the best of what html5 can do? //sacrasti mode off

  • http://active.tutsplus.com Ian Yates

    If any of you cats are interested, we’ve just launched a series: Box2D for Flash and AS3 over on Activetuts+ (see you there :))

  • http://sharing-q.blogspot.com tria xc

    Great tutorial! ,

  • http://www.piotrnalepa.pl Piotr Nalepa

    But there’s almost no documentation for JS. Interesting but useless anyway.

  • http://www.iamkumaran.com/ Muthu Kumaran

    Nice tutorial. I created a animation using Box2d, you should take a look at it,
    http://www.iamkumaran.com/my-first-html5-canvas-box2d-animations/

  • jjaja

    what editor do i use for that

  • Aritz

    If you want make HTML5 games, I suggest Construct 2 from Scirra: scirra.com

  • http://mjstk.co.uk/dev/ MJSTK

    I made a JS Box2d experiment a while back, but it uses CSS3 transforms rather than drawing to canvas, and a unistroke recognizer to allow new objects to be made. The shapes are a crate which is a square and a beam with is similar to the ] shape – demo up here (draw to make shapes, arrow keys to move)

    http://mjstk.co.uk/dev/box2d/

    • Tony

      Dude your site has some pretty neat stuff, nice work, a lot better than this beast.
      Anyone get past the first pillar ?

      • Tony

        nevermind I just beat the game, had to do it in hard mode and a couple of tries later lol

  • PixelTunnelVision

    Correction: Make “another” game with javascript, something people have been using for over a decade to make complex video games. To be fair, using html5 here is at least somewhat new. So I’ll give you that.

    1200 js files later…

  • Dare

    meh I’ll still stick to Flash for now.

  • Tony

    I don’t get it why some developers abuse HTML5 calling everything they like with HTML5 meaning.
    Please show me which HTML5 tags was ONLY used to create this “HTML5 Game” ? no? no you can’t? of course you can’t since this is actually a JavaScript game !

    This way we can call all Flash games as HTML5 games, we include Flash content with HTML tags, same as JavaScript.
    Then we could also call Java games HTML5 games etc etc….

    Also you emphasis that JS files should be concatenate but you provide source file with ‘scattered’ files, but you highly recommend to concatenate… but you don’t show it…

    And look at how much JS code is there for such simple game and you call this Easily developed game…. did you ever used Flash ? it’s at least 10x times easier to create game in Flash than with JavaScript, well dynamic-interactive content of any kind for that matter.

    • bgood

      Hey stupid, it’s html5 because is html5…

  • http://www.html5gameengines.com html5 game engine

    Great tutorial. The time is definitely ripe for HTML5 games now!

  • Matt

    Is there any way that you can stop the screen from scrolling up when you make the ball jump? Its really spoils the game play when you can’t see what you’re doing.

  • http://mauricioquito.com Mauricio

    This has been a great tutorial. You can now also use the app Hype http://tumultco.com/hype/ on macs to develop flash looking sites or I guess even games too. Hype is available at the AppStore for like $39 but you can also get it in a bundle along with more than $500 worth of stuff for only $49.

    Check it at http://bit.ly/n6JPni and join the cause.

  • http://fthok77.blogspot.com Firmansyah

    Im confuse with this program…
    Huft…

    But, i try to understand this program…
    How can explain to me???

  • http://n/a shuvo

    Physics Rulzzz

  • http://www.scirra.com Tom Gullen

    Hey, have you seen our HTML5 game engine (Construct 2)? There’s a free edition available and it means making HTML5 games really easy. http://www.scirra.com/construct2

  • Dipankar

    the game is quite hard to play.

  • http://www.ab-softcon.net Andreas

    Hello,

    great tutorial, but what’s the reason that is does not work in Internet Explorer 9?

    It just does not react on any keyboard input in IE9.

    Best regards
    Andreas

  • http://www.prada-outlet168.com Prada Outlet

    Prada is the most famous luxury brand in the world. We think you should come to Prada Outlet Store Online if you want to buy Prada Outlet Store products. The outlet online is a professional supplier of Prada Factory Outlet. The management idea of Prada Outlet Online is customers must come first. To meet the customers’ demand, here not only provides you cheap high-quality products but also free shipping and fast delivery. So will you choose Prada Outlet to buy prada commodities?

    • http://Patrickleiser.weebly.com Someone

      Spam!!!!!!!!

  • Jose Viscasillas

    Amazing!!!. Great tutorial.