Using RUBE (Really Useful Box2D Editor) in your Flash AS3 projects
I always follow with great interest iforce2d‘s tutorials because they are plenty of interesting ideas. I was inspired by one of such tutorials when I wrote Flying arrows simulation with Box2D and Box2D flying arrows engine – first attempt, so when I realized the author released a full featured Box2D editor called RUBE (Really Useful Box2D Editor) I absolutely wanted to try it.
Following my rule “no pointless reviews”, let me say RUBE is awesome, a must have if you are a Box2D developer. Fullstop.
Now, let me show you how to use it to improve our AS3 coding, since it does not export AS3 code, and it includes more features than the ones included in AS3 v2.1a version.
Although the editor is really powerful and fully documented allowing you to do in a few minutes stuff like this:

I’ll start with a simpler project, building the totem of the first level of Totem destroyer. Here is what I did with RUBE:

And once I export the world in JSON, everything is coded inside, from fixtures to world gravity, from body types to velocities, and so on.
This is the JSON I got from my totem:
|
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
{ "allowSleep" : true, "autoClearForces" : true, "body" : [ { "angle" : 0, "angularVelocity" : 0, "awake" : true, "fixture" : [ { "density" : 1, "friction" : 0.2000000029802322, "name" : "fixture1", "polygon" : { "vertices" : { "x" : [ 2.50, 2.50, -2.50, -2.50 ], "y" : [ -1.0, 1.0, 1.0, -1.0 ] } } } ], "linearVelocity" : 0, "massData-I" : 24.16666603088379, "massData-center" : { "x" : 1.937150884145922e-008, "y" : 2.980232283178452e-009 }, "massData-mass" : 10.0, "name" : "brick", "position" : { "x" : 10.66670036315918, "y" : 5.50 }, "type" : 2 }, { "angle" : 0, "angularVelocity" : 0, "awake" : true, "fixture" : [ { "density" : 1, "friction" : 0.2000000029802322, "name" : "fixture1", "polygon" : { "vertices" : { "x" : [ 2.0, 2.0, -2.0, -2.0 ], "y" : [ -0.50, 0.50, 0.50, -0.50 ] } } } ], "linearVelocity" : 0, "massData-I" : 5.666666507720947, "massData-mass" : 4.0, "name" : "brick", "position" : { "x" : 10.16670036315918, "y" : 4.0 }, "type" : 2 }, { "angle" : 0, "angularVelocity" : 0, "awake" : true, "fixture" : [ { "density" : 1, "friction" : 0.2000000029802322, "name" : "fixture1", "polygon" : { "vertices" : { "x" : [ 1.50, 1.50, -1.50, -1.50 ], "y" : [ -0.50, 0.50, 0.50, -0.50 ] } } } ], "linearVelocity" : 0, "massData-I" : 2.50, "massData-center" : { "x" : -7.450580596923828e-009, "y" : -2.483526939656144e-009 }, "massData-mass" : 3.0, "name" : "brick", "position" : { "x" : 10.66670036315918, "y" : 3.0 }, "type" : 2 }, { "angle" : 0, "angularVelocity" : 0, "awake" : true, "fixture" : [ { "density" : 1, "friction" : 0.2000000029802322, "name" : "fixture1", "polygon" : { "vertices" : { "x" : [ 2.50, 2.50, -2.50, -2.50 ], "y" : [ -0.50, 0.50, 0.50, -0.50 ] } } } ], "linearVelocity" : 0, "massData-I" : 10.83333301544190, "massData-center" : { "x" : 1.937150884145922e-008, "y" : 1.490116141589226e-009 }, "massData-mass" : 5.0, "name" : "brick", "position" : { "x" : 10.66666603088379, "y" : 2.0 }, "type" : 2 }, { "angle" : 0, "angularVelocity" : 0, "awake" : true, "fixture" : [ { "density" : 1, "friction" : 0.2000000029802322, "name" : "fixture1", "polygon" : { "vertices" : { "x" : [ 0.50, 0.50, -0.50, -0.50 ], "y" : [ -0.50, 0.50, 0.50, -0.50 ] } } } ], "linearVelocity" : 0, "massData-I" : 0.1666666716337204, "massData-mass" : 1, "name" : "brick", "position" : { "x" : 12.66666698455811, "y" : 1 }, "type" : 2 }, { "angle" : 0, "angularVelocity" : 0, "awake" : true, "fixture" : [ { "density" : 1, "friction" : 0.2000000029802322, "name" : "fixture1", "polygon" : { "vertices" : { "x" : [ 0.50, 0.50, -0.50, -0.50 ], "y" : [ -0.50, 0.50, 0.50, -0.50 ] } } } ], "linearVelocity" : 0, "massData-I" : 0.1666666716337204, "massData-mass" : 1, "name" : "brick", "position" : { "x" : 8.666660308837891, "y" : 1 }, "type" : 2 }, { "angle" : 0, "angularVelocity" : 0, "awake" : true, "fixture" : [ { "density" : 1, "friction" : 0.2000000029802322, "name" : "fixture0", "polygon" : { "vertices" : { "x" : [ 10.66666984558106, -10.66666030883789, -10.66666030883789, 10.66663932800293 ], "y" : [ 0.50, 0.50, -0.50, -0.50 ] } } } ], "linearVelocity" : 0, "name" : "ground", "position" : { "x" : 10.66666030883789, "y" : 0 }, "type" : 0 } ], "continuousPhysics" : true, "gravity" : { "x" : 0, "y" : -10.0 }, "positionIterations" : 3, "stepsPerSecond" : 60.0, "subStepping" : false, "velocityIterations" : 8, "warmStarting" : true } |
Now it’s time to import the JSON in our AS3 class, decode it and build the Box2D world out of it. Since this is just an example, I am retrieving only body types, positions and fixtures, but obviously you can build the whole world.
Before you start, download and install Mike Chamber’s as3corelib which offers a great JSON support.
This is the commented script:
|
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
package { import flash.display.Sprite; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLRequest; // JSON library import com.adobe.serialization.json.JSON; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Contacts.*; public class Main extends Sprite { private var worldScale:Number=30; private var world:b2World=new b2World(new b2Vec2(0,10),true); public function Main() { debugDraw(); // loading the JSON file var urlReq:URLRequest=new URLRequest("totem.json"); var urlLoader:URLLoader=new URLLoader(urlReq); // once read, the core of the script is JSONLoaded function // which will render the Box2D world urlLoader.addEventListener(Event.COMPLETE, JSONLoaded); addEventListener(Event.ENTER_FRAME, update); } private function JSONLoaded(e:Event):void { // jsonData string holds the content of totem.json file var JSONData:String=String(e.target.data); // converting the string into a JSON object var JSONObject:Object=JSON.decode(JSONData); // looping through all JSON->body array for (var i:Number=0; i<JSONObject.body.length; i++) { // at this time bodyObject is the object representing the i-th body var bodyObject:Object=JSONObject.body[i]; // retrieving body position as i-th body->position->x and i-th body->position->y var pX:Number=bodyObject.position.x; var pY:Number=bodyObject.position.y; // same thing for the vertices var verticesX:Array=bodyObject.fixture[0].polygon.vertices.x; var verticesY:Array=bodyObject.fixture[0].polygon.vertices.y; // I have to push the vertices into a vector because every polygon is defined // by a series of vertices even if is just a box var points:Vector.<b2Vec2>=new Vector.<b2Vec2>(); for (var j:Number=0; j<verticesX.length; j++) { points.push(new b2Vec2(verticesX[j],verticesY[j])); } // body creation var bodyDef:b2BodyDef=new b2BodyDef(); // look at body y position to prevent it to be upside down bodyDef.position.Set(pX,480/worldScale-pY); bodyDef.type=bodyObject.type; var polygonShape:b2PolygonShape=new b2PolygonShape(); polygonShape.SetAsVector(points,j); var fixtureDef:b2FixtureDef=new b2FixtureDef(); fixtureDef.shape=polygonShape; fixtureDef.density=1; fixtureDef.restitution=1; fixtureDef.friction=1; var theWall:b2Body=world.CreateBody(bodyDef); theWall.CreateFixture(fixtureDef); } } private function debugDraw():void { var debugDraw:b2DebugDraw=new b2DebugDraw(); var debugSprite:Sprite=new Sprite(); addChild(debugSprite); debugDraw.SetSprite(debugSprite); debugDraw.SetDrawScale(worldScale); debugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit); debugDraw.SetFillAlpha(0.5); world.SetDebugDraw(debugDraw); } private function update(e : Event):void { world.Step(1/30,5,5); world.ClearForces(); world.DrawDebugData(); } } } |
And this is the result:
The totem is done in just a few lines of code, but obviously the most interesting thing is I would have been able to build a totem made by 1000 bricks in exactly the same amount of lines.
Download the source code with all required libraries. I am also going to create a RUBE to AS3 class to have the ultimate Box2D editor.
They can be easily customized to meet the unique requirements of your project.














This post has 18 comments
Jimmie
Throws an Error for me:
Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: http://www.emanueleferonato.com/2012/12/19/using-rube-really-useful-box2d-editor-in-your-flash-as3-projects/totem.json
at Main()
Looks like the url for that file doesn’t exist or isn’t loading.
Diogo
The first image of the post is not showing, and the flash is an enpty gray area :(
Emanuele Feronato
fixed! thank you!!
payampap
Thank You
Usefull
iforce2d
Wow, that was fast. Nice job!
Using RUBE (Really Useful Box2D Editor) in your Flash AS3 projects – Emanuele Feronato « eaflash
[...] on http://www.emanueleferonato.com Share this:TwitterFacebookLike this:LikeBe the first to like [...]
cnsoft
it seems that adobe has provide original json process function. no need use that as3corelib.
codeBeast
1. new json function is for flash player 11 so it’s still a good idea to use the as3corelib as you need to make games available to the widest possible audience.
2. I am mucking around with the editor an yes it’s amazing. I hope you post a few more tutorials with regards collision testing etc… or does that have to be taken care of like always in Box2d and this is merely a tool for developing the visuals.
3. Performance: Is the json file translated straight to box2d code and the performance therefore exactly the same as normal Box2d ie: Slow on mobile???
Husky
Pretty cool!
Jacques
Emanuele, this is great. I didn’t know about RUBE until this post. I’m curious to know how you would compare this tool to using the World Construction Kit (http://www.sideroller.com/wck/)? The WCK is my general go-to framework for my Box2D projects, but with a good RUBE to AS3 class, I might make the switch :)
Julio
hey there just a question
can i use this editor to get the code and use it in javascript box2dweb???
do you know any box2dweb editor like this?
thanks and sorry for my bad english =D
iforce2d
Julio
There are some box2dweb examples on the main page, and in the trial download :)
Simon
Hi Emaneuele, thanks for posting the tutorial it’s been a great help. I’ve run into a problem though after I bought R.U.B.E and am trying to load my own level:
After parsing the JSON file and creating the box2d world everything is upside down, even with the y-pos check you have when creating each body. Anything I may have missed?
jonathan
Hey Emanuele,
Thank you for all the post you’ve done, I mean, about everything. This is just very generous.
Thank to this post, I’ve decided to use RUBE to create my world.
I’ve adapted your code to work with customs body (multiple fixtures).
There was only one line in your code that I did’nt get:
“// look at body y position to prevent it to be upside down”
As my world was looking good, mostly very similar shapes, I didn’t pay attention that they were upside down…
But still at the right position…
Could you explain how to avois that? I mean, if you have few secondes… of course.
Thank you again anyway.
Jonathan
Gilles
Hey,
Awesome stuff, I’m suprised that tool is not really well known.
I saw you can also have custom properties to your objects. I’ll work on some full starling/box2d integration in my next game project.
Small question : I didn’t try http://www.sideroller.com/wck/. Is it that faster than as3 box2d lib, because I don’t see much update since a year.
Nice work, cheers.
Gilles
Hey,
Awesome stuff, I’m suprised that tool is not really well known.
I saw you can also have custom properties to your objects. I’ll work on some full starling/box2d integration in my next game project.
Small question : I didn’t try http://www.sideroller.com/wck/. Is it that faster than as3 box2d lib, because I don’t see much update since a year.
Nice work, cheers.
Sharat
Hi Emaanuele,
I have tried your material. It was very useful to integrate JSON into flash. I was wondering. I get an error when i include a circle in the scene. Do i have to define circle as well because the defection is only for polygons. How can i load all the data of the JSON file including density, restitution and friction. I could not get to do that and also do i acess the objects that have been created with the JSON file.
Thank you very much for the light on this topic.
Regards,
Sharat
Sharat
Solved the problem by making different objects before JSONLoaded event. Really awesome. Thanks you so much for the Light towards this topic.
Regards,
Sharat