Solomon Eseme A software developer who is geared toward building high-performing and innovative products following best practices and industry standards. I also love writing about it at Masteringbackend. Follow me: Twitter, Facebook, LinkedIn, about.me

Intro to Boxbox.js: Building an ‘Angry Birds’ clone with JavaScript

2 min read 755

Intro to Boxbox.js: Building an `Angry Birds` Clone With JavaScript

The idea of creating games with JavaScript may seem daunting at first if you aren’t familiar with the basics, such as how to get started, the various game engines available to streamline the development process, etc.

In this guide, we’ll demonstrate how to use Boxbox.js and Box2D by building a simple “Angry Birds” clone. We’ll focus on how to create JavaScript Boxbox.js entities and blocks and how to represent real-world objects with it.

Getting started with Boxbox.js and Box2D

Before we delve into coding, let’s quickly go over the libraries we’ll be using to develop our game.

Boxbox.js is a JavaScript framework for making games. It uses the Box2d engine under the hood, which is very difficult for beginners to get around with at first glance. Boxbox.js helps simplify the process of creating simple and fun 2D games with the Box2D library.

First, download and add the libraries to your HTML file.

Create an index.html file and add the following code.

<html>
  <head>
    <script src="https://github.com/hecht-software/box2dweb/blob/master/Box2d.min.js"></script>
    <script src="https://github.com/incompl/boxbox/blob/master/boxbox.min.js"></script>
  </head>
  <body>
    <main>
      <canvas id="angrybird" width=640 height=380></canvas>
    </main>
    // Added our custom Game
    <script src="AngryBird.js"></script>
  </body>
</html>

Setting up the canvas

Create a file called AngryBird.js and paste in the following initialization code.

const canvas = document.getElementById("angrybird");
const ourWorld = boxbox.createWorld(canvas);

Using the ourWorld object, we can call the createEntity method to create various types of entities or objects in our ourWorld.

Creating our bird and ground entities

In the case below, we’re creating a circle entity called bird. As you’ve probably guessed by now, we’re going to represent our bird as a circle.

We’ll give our bird the following properties below and added an onKeyDown function to trigger the bird to jump at any key down event.

We made a custom demo for .
No really. Click here to check it out.

ourWorld.createEntity({
  name: "bird",
  shape: "circle",
  radius: 1,
  imageStretchToFit: true,
  density: 4,
  x: 2,
  onKeyDown: function (e) {
    this.applyImpulse(200, 60);
  },
});

Next, we’ll create another entity called ground, which will represent our floor. In the world of physic, if anything is not blocking an object or if it is not set to static, gravity will move it downward below the surface.

To avoid losing our entities, we created the ground entity with the following properties. We should also make sure it’s set to static so it doesn’t move downward.

ourWorld.createEntity({
  name: "ground",
  shape: "square",
  type: "static",
  color: "rgb(0,0,0)",
  width: 20,
  height: 0.5,
  y: 12.5,
});

Building obstacles

The following code creates a block, which will represent the obstacles for our bird to hit. Since we’ll be generating three of the same type of block, it’s a good idea to create a since object to represent it.

const block = {
  name: "block",
  shape: "square",
  color: "red",
  width: 0.5,
  height: 4,
  onImpact: function (entity, force) {
    if (entity.name() === "bird") {
      this.color("black");
    }
  },
};

Using the block generated above, we created our first obstacle with the following unique property.

ourWorld.createEntity(block, {
  x: 15
}

Using the the block generated above, we created our second obstacle with the following unique property.

ourWorld.createEntity(block, {
  x: 17
}

Using the the block generated above, we created our third obstacle with the following unique property.

ourWorld.createEntity(block, {
  x: 16,
  y: 1,
  width: 4,
  height: .5
}

Finalizing our game

Putting the above code together produces the code below.

const canvas = document.getElementById("angrybird");
const ourWorld = boxbox.createWorld(canvas);

ourWorld.createEntity({
  name: "bird",
  shape: "circle",
  radius: 1,
  imageStretchToFit: true,
  density: 4,
  x: 2,
  onKeyDown: function (e) {
    this.applyImpulse(200, 60);
  },
});

ourWorld.createEntity({
  name: "ground",
  shape: "square",
  type: "static",
  color: "rgb(0,0,0)",
  width: 20,
  height: 0.5,
  y: 12.5,
});

const block = {
  name: "block",
  shape: "square",
  color: "red",
  width: 0.5,
  height: 4,
  onImpact: function (entity, force) {
    if (entity.name() === "bird") {
      this.color("black");
    }
  },
};

ourWorld.createEntity(block, {
  x: 15,
});

ourWorld.createEntity(block, {
  x: 17,
});

ourWorld.createEntity(block, {
  x: 16,
  y: 1,
});

If you did everything right, your “Angry Birds” clone game should look like this.

Angry Bird

For next steps, you might consider including images, for example, to make the circle look like a bird — or, really, anything you can imagine.

Conclusion

In this article, we demonstrated how to create a simple 2D game using JavaScript and how to create an “Angry Birds” clone using BoxBox.js.

What will you build with this new knowledge? Feel free to share in the comments.

Are you adding new JS libraries to improve performance or build new features? What if they’re doing the opposite?

There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.

LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.

https://logrocket.com/signup/

LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.

Build confidently — .

Solomon Eseme A software developer who is geared toward building high-performing and innovative products following best practices and industry standards. I also love writing about it at Masteringbackend. Follow me: Twitter, Facebook, LinkedIn, about.me

Leave a Reply