Search This Blog

Box2D JavaScript Example Walkthrough

Sponsor: Register today for New Game, the conference for HTML5 game developers. Learn from Mozilla, Opera, Google, Spil, Bocoup, Mandreel, Subsonic, Gamesalad, EA, Zynga, and others at this intimate and technically rich conference. Join us for two days of content from developers building HTML5 games today. Nov 1-2, 2011 in San Francisco. Register now!

This is the second article in a Box2D series, following the Box2D Orientation article.

The Box2DWeb port of Box2D contains a nice example to show off the basics of integrating physics simulations into your web app. This post will provide a walkthrough of the example, explaining the high level concepts and code.

With setInterval, the browser has no idea about your intention. It can't help you optimize accordingly, as it's not apparent you are trying to animate efficiently. With requestAnimationFrame, though, the browser understands what you are trying to do, and can help. It will even turn off animations if the tab isn't visible, saving power and battery. Mr. Paul Irish has a nice cross-browser solution for requestAnimationFrame, even falling back to older browsers.

Remember from our previous Box2D Orientation that Box2D likes to operate on objects between 0.1 meters and 10 meters. You should not use pixels as your units, otherwise Box2D would be trying to simulate dust particles or cruise ships. You will often see Box2D code specify a scale factor, usually around 30.

The World

A Box2D world requires a gravity vector and a boolean to signal if objects at rest should be put to sleep. Note that Box2D doesn't assume gravity falls straight down at 9.8 m/s/s.

Older versions of Box2D required you to define the size of the world. Versions 2.1 and later (at the time of this writing, Box2D is now up to 2.2) do not require a predefined world size.

A Body Definition defines where in the world the object is, and if it is dynamic (reacts to things) or static. A Body Definition's position is set to the middle center-point of the object, which is different than the normal upper left of HTML5 Canvas.

You'll be happy to know that Box2D provides for a simple debug drawing output, allowing you to easily see what's happening in your world. You need to specify the scale into the graphics canvas (typically 30, as mentioned above) and provide a reference to the HTML5 Canvas.

Stepping through the simulation requires three configuration values: the time step, the velocity iteration count, and the position iteration count.

Box2D recommends keeping the time step constant. For example, don't tie the simulation time step to the frame rate, as frame rate can really vary during a game. The Box2D manual will suggest a 60Hz time step, which is 1/60 seconds.

The velocity phase "computes the impulses necessary for the bodies to move correctly." Box2D will suggest a velocity iteration count of 8, but you can change this depending on your needs. It's a trade-off between performance and accuracy.

The position phase "adjusts the positions of the bodies ro reduce overlap and joint detachment." The recommended value is 3, though you can change this with the same performance and accuracy trade-offs. The position phase might exist early if the solver determines the errors are small enough.

Hopefully we've demystified Box2D a bit here, at least for the simple case. It's important to know that Box2D can do more than what we've shown here. For example, you can model different kinds of joints, add callbacks for when two objects are touching (sensors), and set velocity, amongst other options.

What do you want to see next for our Box2D series? Thanks for following along!

Popular posts from this blog

Now, this has to have a built-in somewhere in Scala , because it just seems too common. So, how to convert an Array to a List in Scala? Why do I need this? I needed to drop to Java for some functionality, which in this case returns an Array. I wanted to get that Array into a List to practice my functional programming skillz. **Update**: I figured out how to convert Arrays to Lists the Scala way. Turns out it's a piece of cake. val myList = List.fromArray(Array("one", "two", "three")) or val myList = Array("one","two","three").elements.toList The call to elements returns an Iterator , and from there you can convert to a List via toList . Nice. Because my first version wasn't actually tail recursive, what follows is a true tail recursive solution, if I were to implement this by hand. The above, built in mechanism is much better, though. object ArrayUtil { def toList[a](array: Array[a]): List[a] = { d

In which I port a snazzy little JavaScript audio web app to Dart , discover a bug, and high-five type annotations. Here's what I learned. [As it says in the header of this blog, I'm a seasoned Dart developer. However, I certainly don't write Dart every day (I wish!). Don't interpret this post as "Hi, I'm new to Dart". Instead, interpret this post as "I'm applying what I've been documenting."] This post analyzes two versions of the same app, both the original (JavaScript) version and the Dart version. The original version is a proxy for any small JavaScript app, there's nothing particularly special about the original version, which is why it made for a good example. This post discusses the differences between the two implementations: file organization, dependencies and modules, shims, classes, type annotations, event handling, calling multiple methods, asynchronous programming, animation, and interop with JavaScript libraries. F

In which the virtues of automated mechanical arboreal pruning are extolled over quaint manual labor, as applied to web development build processes. The setup Ever notice how the primary bit of marketing for many traditional web programming libraries is their download size? Why is that? Check this out: Why does size matter so much for these libraries? Your first instinct is probably, "because the more bytes you shuttle across the wire, the slower the app starts up." Yes, this is true. I'd also say you're wrong. The primary reason that size matters for these libraries is because traditional web development has no intelligent or automated way to prune unused code so you can ship only the code that is used over the wire. The web is full of links, yet web dev has no linker The web development workflow is missing a linking step. A linker's job is to combine distinct project files into a single executable. A smart linker will only incl