Box2Dflash Version 2.0 ported Javascript
Please note that this is experimental code! If you use this please let me know and give Erin Catto and me some credit.
Some weeks ago I wrote a script to convert version 2.0.2 of Box2DFlash to Javascript. I hesitated to release it because it is basically one big nasty hack that just happens to work. But as I got a few requests for it so I decided to release it. Please let me know if you do something with it. :)
Demo
You can see a demo of it in action here. You can click to trigger an explosion. On my notebook the demo runs fluidly in chrome. In firefox 3.5 it is pretty slow. In the current nightly it runs smooth as well. So I guess firefox is slowly catching up. Oh and just forget about IE.
Approach
At first thought this conversion would be trivial as both actionscript and javascript are dialects of ECMAScript. Well, I was wrong. Nevertheless I continued to follow my regex based approach, basically trying to ram my head through a wall. After a few attempts I succeeded to convert Box2DAS3 to javascript. It had a nasty bug tough. Two solid cubes were able to penetrate each other when the fell on their edges. The reason? ActionScript supports 'properties'. I didn't know about this and the conversion script does not support it. In the end I fixed the few properties in the translated code by hand because I was to lazy to add support for getters and setters to the conversion script. Now it seems to work pretty well. Please keep in mind, this is not a generic actionscript to javascript compiler, it's just a script that happens to work for box2dflash.
The explosions in the demo are simulated by shooting out a few tracer particles with a high density and velocity. The benefit over just applying an impulse to each object is that the strength of the impulse is proportional to the surface area. Also the force of the explosion will to some extend be redirected to the side by the floor. When using this in production code you would probably want to destroy this tracer particles after their first collision or a few seconds.
Please keep in mind, I'm not an expert on the subject. There are probably better and faster ways to approximate this than my crude way of using tracer particles (Navier-Stokes in javascript anybody? ;) ). Maybe I'll try to do some fluid dynamics on the gpu using webgl some day. It would be cool for sure.
Compiled Script
I compiled a single file version of the script using googles closure compiler. box2d.js.
Complete Zip
The zip file contains the actionscript source, the conversion script and a patch to fix some of the things the conversion script misses. box2d2.zip
Github
Documentation
I didn't write any. But you can use the documentation of box2dflash.
Jonas Wagner
Nice! You could also fake explosions by applying forces to all the elements on the simulation based on the mouse position where you clicked. Dirty but at least you make sure all the objects get affected, with your approach it can happen than an object gets through in between bullets.
By the way, you're aware of Box2DJS, right?
box2d-js.sourceforge.net/
Comment by Mr.doob — 4/18/10 10:03 PM | # - re
Yeah, I am aware of that port. But it is based on an older version of box2d. The problem with just applying the force is that all objects will usually get the same impulse. But the impulse does depend on the surface exposed to the explosion. I guess the best example is objects behind a solid wall. They shouldn't be affected at all.
Comment by Jonas Wagner — 4/18/10 10:21 PM | # - re
Yeah. This is a port of 2.0. It's good, just wanted to make sure you knew the other one :)
The impulse can be applied with some decay using distance. But yeah, the wall example ruins my approach :(
Comment by Mr.doob — 4/19/10 12:24 AM | # - re
Wait. There is a much simpler solution. Instead of throwing a circle of bullets. Just throw a bullet in the direction of each object on the simulation from the mouse position. It's not 100% perfect, as 2 objects may be in the same direction, but should be good enough I think.
Comment by Mr.doob — 4/22/10 5:26 AM | # - re
It's still problematic though. First all boxes will get the same impulse independant of the distance to the explosion (well virtually, the particles are effected by gravity). The other problem is that an object with a bigger surface area exposed to the explosion should get a stronger impulse. The last problem I see is that scenes will often contain more than 25 (thats the number of tracer particles I currently use) objects. So it will be more expensive.
Comment by Jonas Wagner — 4/22/10 10:36 AM | # - re
So beautiful :) But Isn't it simpler to make a code like that using jQuery ?
Comment by Fandekasp — 5/2/10 5:32 AM | # - re
I think with something simple like this, it would be feasible to sacrifice realism and go with applying an impulse to all nearby objects with a distance curve. It would probably work better than the way it is currently set up, imo, as the explosion particles can often miss objects, which is quite unrealistic as it is.
Comment by SumWon — 5/19/10 9:58 AM | # - re
Forgot to mention, great work!
Comment by SumWon — 5/19/10 9:59 AM | # - re
In this specific demo you are surely right. In a game I wouldn't go that way though. Because of the issues mentioned above. Using some mathematical magic it would even be possible to send out particles to each object was well as random ones while keeping the distribution normalized.
Comment by Jonas Wagner — 5/19/10 11:24 AM | # - re
Hi. I'm trying to make use of this library to create a sidescrolling platformer ( WIP: creativepony.com/games/Beatmatch/ use keys d, b, o, and j, to do stuff, arrow keys to move character ) but am having trouble implementing jumping in the player character. I'm trying to use b2World.Query to find out if there are any shapes immediately under the character, and use that to decide if they are allowed to jump or not. Query seems to always return zero results in your port though?
I've tried creating an AABB as big as the world boundaries, and queried that and still received zero results, and a seemingly untouched results array. I've been looking around in the source code hoping to find some clues, but haven't found anything obviously wrong with your Box2d port. Do you have the foggiest of ideas as to what's going on?
Comment by Jenna Fox — 6/2/10 3:25 AM | # - re
I also note that you can test this by running:
world.Query(world.m_broadPhase.m_worldAABB, [null, null], 2);
in your javascript console, and seeing if the number is 2, or 0. It should be 2. On your own demo page, it is 0, while on the older 1.x port's demo page, it is 2.
Comment by Jenna Fox — 6/2/10 3:29 AM | # - re
Hi Jenna,
Thanks for trying it out. I'll have a look at the problem. It might take a little time though. I'll send you a mail when I know more.
Cheers,
Jonas
Comment by Jonas Wagner — 6/2/10 8:58 PM | # - re
Alright, thanks heaps! Meanwhile: You have my admiration for that realtime raytracer! :)
Comment by Jenna Fox — 6/3/10 12:53 AM | # - re
This is exactly what I was looking for. Thanks. I am in the process of porting this to a nodejs module so that game servers written in Javascript will have access to the physics simulation and collision detection. Check it out at github.com/jadell/box2dnode and let me know what you think. Great work!
Comment by Josh Adell — 6/19/10 12:04 AM | # - re
Hi Josh,
That's pretty cool, thanks for letting me know. :)
Cheers,
Jonas
Comment by Jonas Wagner — 6/19/10 7:52 PM | # - re
Hi Jonas!
Great work with box2D!
I've tried the box2d.js and it works perfectly, otherwise it doesn't work if I use as load.html says.
It crashes when I try: var world = new b2World(worldAABB, gravity, doSleep);
Comment by Danilo Cesar — 7/30/10 9:10 PM | # - re
Hi,
Wow! Your python script is quite non-trivial.
I have recently been playing with box2d-js. I initially wanted to see how SVG would perform over Canvas, but I ended up optimising other parts of the core library as well.
Demo and source code are here:
lavadip.com/box2d_demo/index.html
I found your port of the library a bit slower than the original box2d-js port (which is based on box2d 1.4). Not completely surprising since it is automated conversion.
Perhaps we should work together in optimising your port. Are you interested?
Comment by HRJ — 7/31/10 8:23 AM | # - re
Hehe, 'quite non-trivial' is a nice way of saying it's a mess. :-) I currently don't have the time to work on box2djs, but I created a github project so feel free to fork it and ask me questions.
Comment by Jonas Wagner — 7/31/10 5:50 PM | # - re
Using our tool Jangaroo, we managed to automatically compile the latest version of Box2DFlash to JavaScript. A live demo can be found here: www.jangaroo.net/files/examples/flash/box2d/Have a look at the HTML source code to see what you have to do to load the framework and example code. The idea is to still develop using ActionScript, then compile with Jangaroo and run in the browser. But you can also use the compiled framework directly from JavaScript. I'll soon put a project on github to get you started!
Comment by Frank — 8/28/10 2:28 PM | # - re
Hi Frank, That looks pretty cool, surely better than my conversion script. The demos seem to be very slow in firefox though.
Cheers,
Jonas
Comment by Jonas Wagner — 8/29/10 1:14 AM | # - re
Hey Jonas,
This is really cool, I am using it at present for a top-down action game I am making that has dynamically generated dungeons.
My only gripe is that its not version 2.1, so I cannot use edge shapes (boxes will do for now though)!
There is another developer called Uli Hecht who is also trying to work on a Box2D port of 2.1, but his version is apparently not yet completely stable -- see code.google.com/p/box2dweb/issues/entry
and demo at
www.tornadoentertainment.de/Box2dWeb/demo/example.html
Maybe you guys should merge your efforts...
Comment by Nick Wiggill — 10/25/10 2:33 PM | # - re
Thank you for your work, Jonas!
I am trying to build a readable, uncompressed box2d-dev.js version but code.google.com/p/closure-compiler/issues/detail?id=249 prevents me to do so. Before I am going to change the declaration of the properties by hand: How did you convince closure to compile the files?
Comment by Heiko Behrens — 1/8/11 12:38 AM | # - re
Hi Heiko,
I did not encounter the problem with the version of closure compiler I used. But I have checked the output now and it seems to mess up getters and setters. :( I can send you the version I used if want.
cheers,
Jonas
Comment by Jonas Wagner — 1/10/11 11:08 AM | # - re
Is that a Ubuntu cursor in the screenshot? Awesome!
Comment by Tyler — 3/7/11 4:10 AM | # - re
Thanks for creating this, I used it for a WebGL experiment: boblycat.org/~knute/box2dhtml/
Comment by Knut Arild Erstad — 3/14/11 2:35 AM | # - re
Cool stuff, I'm impressed by the performance.
Comment by Jonas Wagner — 3/14/11 7:13 PM | # - re
I'm so glad someone ported version 2, since Bo2DJS doesn't appear to be active.
Has anyone extended this to include additional joint types? Weld, friction, line, or rope?
I'd love to use those, but I think porting them myself is beyond my capabilities :)
Comment by Aaron — 3/16/11 7:08 PM | # - re
Just to make sure i'm not crazy... you didnt really port debugdraw right? Meaning, if I set m_sprite to a canvas, it wont work right?
Comment by steve0 — 4/3/11 2:20 AM | # - re
I'm pretty certain it won't work but I didn't try it.
Comment by Jonas Wagner — 4/3/11 9:15 PM | # - re