Creation of an educational game with Box2D
Since I have a daughter, I love educational games. My daughter learned to count up to 100 and now is learning english thanks to her iPad and a ton of apps I installed.
So, imagine what happened when I saw this video:
I had to do something similar with Box2D.
And here is a brief prototype, still uncommented because it’s rather unfinished, but at least you can pick up boxes with the mouse and put them in their place.
|
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 |
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Joints.*; public class Main extends Sprite { private var world:b2World; private var worldScale:Number = 30; private var mouseJoint:b2MouseJoint; public function Main() { world = new b2World(new b2Vec2(0,9.81),true); debugDraw(); var bodyDef:b2BodyDef=new b2BodyDef(); bodyDef.position.Set(320/worldScale,470/worldScale); var polygonShape:b2PolygonShape=new b2PolygonShape(); polygonShape.SetAsBox(320/worldScale,10/worldScale); var fixtureDef:b2FixtureDef=new b2FixtureDef(); fixtureDef.friction = 1; fixtureDef.restitution = 0.5; fixtureDef.shape = polygonShape; var groundBody:b2Body = world.CreateBody(bodyDef); groundBody.CreateFixture(fixtureDef); for (var i:int=0; i<3; i++) { createBox(Math.random()*500+70,400,b2Body.b2_dynamicBody); var targetBox:TargetBox=new TargetBox(); addChild(targetBox); targetBox.x = 220 + i * 100; targetBox.y = 180; } addEventListener(Event.ENTER_FRAME,updateWorld); stage.addEventListener(MouseEvent.MOUSE_DOWN,createJoint); } private function createBox(pX:Number,pY:Number,type:int):void { var bodyDef:b2BodyDef=new b2BodyDef(); bodyDef.position.Set(pX/worldScale,pY/worldScale); bodyDef.type = type; var polygonShape:b2PolygonShape=new b2PolygonShape(); polygonShape.SetAsBox(30/worldScale,30/worldScale); var fixtureDef:b2FixtureDef=new b2FixtureDef(); fixtureDef.shape = polygonShape; fixtureDef.density = 1; fixtureDef.friction = 0.5; fixtureDef.restitution = 0.2; var box:b2Body = world.CreateBody(bodyDef); box.CreateFixture(fixtureDef); } private function createJoint(e:MouseEvent):void { world.QueryPoint(queryCallback,mouseToWorld()); } private function queryCallback(fixture:b2Fixture):Boolean { var touchedBody:b2Body = fixture.GetBody(); if (touchedBody.GetType() == b2Body.b2_dynamicBody) { var jointDef:b2MouseJointDef=new b2MouseJointDef(); jointDef.bodyA = world.GetGroundBody(); jointDef.bodyB = touchedBody; jointDef.target = mouseToWorld(); jointDef.maxForce = 1000 * touchedBody.GetMass(); mouseJoint = world.CreateJoint(jointDef) as b2MouseJoint; stage.addEventListener(MouseEvent.MOUSE_MOVE,moveJoint); stage.addEventListener(MouseEvent.MOUSE_UP,killJoint); } return false; } private function moveJoint(e:MouseEvent):void { mouseJoint.SetTarget(mouseToWorld()); } private function killJoint(e:MouseEvent):void { world.DestroyJoint(mouseJoint); mouseJoint = null; stage.removeEventListener(MouseEvent.MOUSE_MOVE,moveJoint); stage.removeEventListener(MouseEvent.MOUSE_UP,killJoint); } private function mouseToWorld():b2Vec2 { return new b2Vec2(mouseX/worldScale,mouseY/worldScale); } 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 updateWorld(e:Event):void { world.Step(1/30,10,10); world.ClearForces(); for (var b:b2Body=world.GetBodyList(); b; b=b.GetNext()) { for (var i:int=0; i<3; i++) { var distX:Number = b.GetPosition().x * worldScale - (220 + i * 100); var distY:Number = b.GetPosition().y * worldScale - 180; if (distX*distX+distY*distY<900 && b.GetType()==b2Body.b2_dynamicBody) { world.DestroyBody(b); createBox(220 + i * 100,180,b2Body.b2_staticBody); } } } world.DrawDebugData(); } } } |
And here is the result:
Pick boxes with the mouse and place them in their places.
More to come during next days, can’t way to make something similar for my daughter.
They can be easily customized to meet the unique requirements of your project.














This post has 14 comments
Martin
Hi Emanuele.
Cool to see my video featured here :) thanks!
Its really quite simple to setup this kind of physical scene. But that also what is cool I think, make something simple and then see your kid using it for learning new things.
Great example you did using Box2D. Im a Nape guy myself :)
I got some other videos showcasing the project on my vimeo page.
http://www.vimeo.com/bjeld
Best regards
Martin
fjckls
Nice, have to make one for my kid too :). Btw when is your box2d book coming out?
Bohemme
Good script! It’s incredible how useful can new techonoligies be for education. There’s a typo in your last sentence: …next days, can’t way to make some… *wait
:)
Rahyar
a pretty interesting idea.
tanks :-)
Emre
Please make the stencyl version, I really need it.
Santiago
I’ve done something similar but it was a puzzle with about 9 pieces. Works great on desktop, and terribly slow on an iPad3. Isn’t it better to use Starling to achieve this? Martin, how did you do it?
Martin
Hi Santiago.
I used Combination of Starling and nape. I only use the Starling “Display List”
Santiago
Thanks Martin!
Daniel
Hi, how are you?
How do I run a flash application on iOS (iPad, IPHONE)
as in this example from the video, I made a sample. how to setup html to run flash on iOS?
Todd
Nice share! Thanks!
George
Oh hey Emanuele, that’s nice! My company was working on some educational games also ^^…
Richard
I’m new to programming. Am I correct is saying that you built this program in flash using Box 2d as a framework then compiled the program into an SWC file and ran the Swf part of that file in the code for this webpage in order to create that interactive portion.
Also, It’s my understanding that Box 2d is free, compliers are free, yet flash is not free but seems to be an essential tool for the creation of any animation or game. I have xcode and eclipse, but it’s my understanding that these are not the same as flash.
I AM CONFUSED is really what I’m trying to say.
Richard
I’m new to programming. Am I correct is saying that you built this program in flash using Box 2d as a framework then compiled the program into an SWC file and ran the Swf part of that file in the code for this webpage in order to create that interactive portion.
Also, It’s my understanding that Box 2d is free, compliers are free, yet flash is not free but seems to be an essential tool for the creation of any animation or game. I have xcode and eclipse, but it’s my understanding that these are not the same as flash.
I AM CONFUSED is really what I’m trying to say.
gus
hello there
is there any project like the one viewd on the video ?
it seem nice but this is not complete
any download files or etc for a complete files please :) ?