Creation of an educational game with Box2D

Talking about Educational Game game, Actionscript 3, Box2D, Flash and Game development.

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.

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.

Download the source code.