Tutorial 1: Colliding Blocks

The purpose of this tutorial is to familiarize you with the working of Box2DGame. In this tutorial we will create a box which contains 25 blocks that will bounce around and collide with each other. This is the first in a series of tutorials which are designed to to help you learn how to write games with Box2DGame. The only pre-requisites are a basic understanding of HTML and javascript.

HTML Structure

In order to run Box2DGame on a webpage, the page must contain a div with an id of "game-stage" that is given a fixed width and height. When the page loads, this div will be appended with another div with an id of "pawns" which is used to contain div's which correspond to pawns in the game. It is neccessary to include jQuery, box2dweb, and b2Game javascript source files. Below is a baseline webpage which can be used for the purposes of these tutorials.

game.html
<html>
<body>

<head>
<style>
#game-stage {
width: 1000px;
height: 400px;
}
</style>
</head>

<div id="game-stage"></div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script src="box2dweb.min.js" type="text/javascript"></script>
<script src="b2game.js" type="text/javascript"></script>

</body>
</html>

Before proceeding, create a new file called tutorial.js:

tutorial.js
$(document).ready( function() {

});
and include the following line in the game.html page given above
<script src="tutorial.js" type="text/javascript"></script>

Creating the Walls

The first step is to create the four walls of the box which will contain the bouncing blocks. This is accomplished by making use of the b2Game.Pawn function. Put the following lines into document ready function of tutorial.js, and view the result in your browser.

Wall = function(data) {

this.__proto__ = new b2Game.Pawn({

id: 'wall',
type: 'static',
image: 'images/walltile.jpg',
width: data.width,
height: data.height,
position: {x:data.x,y:data.y},

});

b2Game.pawns[this.id] = this;

}

new Wall({ x: 0, y: 0, width: b2Game.stage.width*30, height: 30});

Let's take a moment to explain what is going on here. We are creating a function Wall() which is always going to be called with the new operator. We have set this.__proto__ equal to a new instance of the b2Game.Pawn function, the arguments passed to b2Game.Pawn determine various properties of the Wall. We are setting the "id" parameter equal to "Wall", this means that every Wall will be represented on the screen by a div with an id of wall_X, where X is the wall number. Since this is the first wall, it will have an id of "wall_1". The "type" parameter is set to "static", this tells the box2d simulation that the position of the Pawn will never change. The "image" parameter is the url of the desired image file. The "width" and "height" parameters are the width and height in pixels of the image. The position is a vector which represents the position coordinates of the top-left corner of the wall in units of meters.

Box2DGame represents the game world using the meters-kilograms-seconds (MKS) system of units. Box2DGame currently using a conversion ratio of 30 pixels per meter. In other words, every 1px on the screen corresponds to 30 meters in the game world.

The final piece of code is b2Game.pawns[this.id] = this;. This line is giving b2Game a pointer to the newly created Pawn Object; this is important because otherwise the Pawn will not call it's update() function during each frame.

Now complete the box by adding three more walls and refresh the browser to see the results. It won't matter that the walls are overlapping because they have been declared as static.

new Wall({ x: 0, y: b2Game.stage.height - 1, width: b2Game.stage.width*30, height: 30});
new Wall({ x: 0, y: 0, width: 30, height: b2Game.stage.height*30});
new Wall({ x: b2Game.stage.width - 1, y: 0, width: 30, height: b2Game.stage.height*30});

Creating the Pawns

The next step is to create a function to create a new block. Add the following code to tutorial.js and refresh the browser to see the result.

Block = function(data) {

this.__proto__ = new b2Game.Pawn({
id: 'block',
type: 'dynamic',
image: 'images/firewall.png',
height: 30,
width: 30,
restitution: 0.5,
friction: 0.2,
position: {
x:data.x,
y:data.y
},
velocity: data.velocity,
});

b2Game.pawns[this.id] = this;

}

for( var i = 0; i <= 25; i++ ) {

new Block({
x: Math.random()*10+5,
y: Math.random()*10+2,
velocity: {
x: (Math.random()-0.5)*10,
y: (Math.random()-0.5)*10
}
});

}

Let's take a look at what's going on here: just like before we are passing a bunch of arguments to a new instance of b2Game.Pawn. In this case, our blocks will be represented by div's which have an id of "block_1", "block_2", and so on. The "type" parameter has been set to "dynamic", which tells the box2d physics engine to treat the block dynamically. The friction has been set to 0.2, this determines how much energy is lost during a collision. The restitution has been set to 0.5, this determines how much bounce each block gets after each collision; a resitution greater than 1 means the block will move faster after it bounces away, and a restitution less than 1 means it will more slower.

The next step is simply to use a for loop to create 25 blocks with random positions and velocities.

Run the Game

Add the following line to your code, and refresh the browser to see the result.

b2Game.run()

That's it! It really is that easy. All of the blocks should fall down and come to rest under the influence of gravity, which by default is set to -10 in the y direction. It is quite simple to change gravity, for example to turn it off you could add the following line to your code:

b2Game.world.SetGravity({ x: 0, y: 0});
In this case we are accessing a standard API call, SetGravity(), from the box2d world Object. You can reproduce the example given above by turning off gravity, setting friction to 0, and restitution to 1. Feel free to experiment with these values.

Box2d is a rich framework which offers a great deal of useful features. For more information on the box2d world object and it's various properties, see the box2d flash documentation.