nest of bees: a javascript and html5 tech demo

Last Saturday I watched an episode of the Deadliest Warrior featuring the Ming Warrior versus the Musketeer.

The Ming Warrior is a real world archer who applied the magic of gun power to his arrow, which when lit, traveled twice as fast and hard. If one takes 30 of these flame darts; gathers them into a hand held wooden crate; and fires them all at once; they become a nest of bees.

I’m basically a pacifist who normally shies away from violence in real life, but within the fantasy of war games, I’m become fascinated by ancient weaponry, especially anything that hurls projectiles like a Trebuchet or Ballista. You’d be right if you guessed that in WoW I played as headwinds, the hunter cow.

Inspired by this episode, I’ve created a Javascript tech demo. Even though it looks like a game, I won’t call it a game because the art and gameplay are obviously god awful. A tech demo or rapid prototype are much more appropriate than a playable game. For the next few weeks, I’ve decided to experiment with box2D, Javascript and the HTML5 canvas tag.

I started my research by doing a google search to find any frameworks supporting box2D and Javascript. While JQuery Physics and box2dweb looked promising, I decided to work with the open source Box2D JS framework by Ando Yasushi simply because it seemed the most accessible, easy to work with, and I liked the example environment which I took and stripped down to the walls.

Prior to the experiment, I did have some Box2D experience but with Flash instead of JS. Last year, I did this simple box2D tutorial. But this time around, I wanted to dive deeper into the framework and finally read the Box2D manual.

At one point, I had the idea that I would use Box2D JS to control the physics while Easel JS would draw and animate the graphics. I even had some crazy rats running around and bouncing off the walls but this also introduced some bizarre behaviors since both frameworks rely on a single timers. I realized that I was trying to be a bit too ambitious and pulled out Easel JS for now, but would like to save animating canvas sprites for another experiment. I wanted to concentrate on learning box2D anyways. I went with static graphics and pointed them at each physics body through userData hooks.

The following is a sample of some javascript. The original demo didn’t have any sprites nor have userData objects applied, and it was rewarding to reach this moment in code when the costumes started to appear when their new update function was called.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var userDataObj = new Object();
userDataObj.name = name;
userDataObj.bodyType = "arrow";
userDataObj.updateCostume = function(b) {
 
   var arrowX = Math.floor( b.GetOriginPosition().x );
   var arrowY = Math.floor( b.GetOriginPosition().y ); 
 
   var c = document.getElementById("nest");
   var cxt=c.getContext("2d");
   var arrowCostume = new Image();
   var imageWidth = 30;
   var imageHeight = 10;
    arrowCostume.onload = function() {
                cxt.save();
		cxt.drawImage(arrowCostume, arrowX, arrowY, imageWidth, imageHeight);
                cxt.restore();
     }
        arrowCostume.src="img/beeArrow.png";
  }
 
  bodyDef.userData = userDataObj;
 
   var dirVec = new b2Vec2();
   var Force_in_Newton = 70;
   var rot = bowRotation; // when rot is 45, both x and y are the same -- increases rot causes x to decrease, and y to increase 
 
   dirVec.x = Force_in_Newton * Math.cos(rot * Math.PI/180);
   dirVec.y = -( Force_in_Newton * Math.sin(rot * Math.PI/180) );
 
    // APPLY VELOCITY TO THE ARROW
    var applyMass = 10; //need at least 10 mass to break gravity
    dirVec.Multiply(applyMass);
    var arrowBody = world.CreateBody(bodyDef);
    arrowBody.SetLinearVelocity(dirVec);

Since Javascript is similar in syntax to Actionscript 1/2, I found these Flash-based tutorials Box2D tutorials and these ones by Allan Bishop to be excellent and I highly recommend them. I was able to port several parts of their AS samples into JS.

As the demo progressed, I dropped certain goals to concentrate on core logic and collision detection. Instead of musketeers, this mighty ming warrior is up against some stiff competition in the form of several terracotta warriors which were easier to animate. I also substituted rocket-powered beehives for arrows after stumbling across a bee dragon sketch by Anthony Holden.

DOWNLOAD

source
demo

FURTHER RESEARCH

If you look at my bloated JS file, I’ve obviously taken a quick-and-dirty, procedural approach that swelled up to this size. Its getting way too unwieldy at a thousand plus lines and my next plan is to refactor it into smaller, manageable classes and separate some of the presentation into CSS. I’d also like to learn more about context transformations as well as the save and restore functions on the canvas as I believe they might clear up the current flickering issues. Besides EaselJS, there are other ways to animate sprites on the canvas that may not compete with the box2d step cycle. I’ve also spent time playing with how box2D behaves within Cocos2D for the iPhone and plan to return to that next applying this new insight.

FINAL THOUGHT

Although at this point I have a lot of visual glitches, I’m impressed with the speed of testing box2D with javascript. I’ve learned a lot but am still scratching my head over the drawing process and have tried several things to reduce it. This is something I haven’t had to think about as much in Flash, but I’m sure this simply from inexperience and I hope to resolve these flickering conflicts over the next couple weeks. If you have any advice, please post any helpful links in the comments.

Like many of my Flash colleagues, I too have come to the decision to begin evaluating Javascript’s potential to create interactive content with new technologies like HTML5. It’s arguably the hottest buzz word in our industry. It’s best to know what its all about and what it can and cannot do. Basically, I wouldn’t want to lose out on an exciting project if I was forced to code with it. And I know “forced” is a strong word here but that, unfortunately, is generally case too. Ideally, it would be great to be able to freely choose between the two depending on the content. It is really refreshing to try out a another language though.

By using Javascript to quickly test and experiment with Box2D, I can apply this knowledge across other languages that support it so that the time I need to work with physics in Flash or i0S I’ll be that much more ahead of the game.

Posted in Indie Gaming, Javascript | Tagged , , , | View Comments