forked from: TestBox2D

by sh0ckwav forked from TestBox2D (diff: 29)
♥0 | Line 142 | Modified 2009-11-18 07:53:43 | MIT License
play

ActionScript3 source code

/**
 * Copyright sh0ckwav ( http://wonderfl.net/user/sh0ckwav )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vPD2
 */

// forked from sh0ckwav's TestBox2D
package {
       import Box2D.Collision.Shapes.b2PolygonDef;
	import Box2D.Collision.Shapes.b2Shape;
	import Box2D.Collision.b2AABB;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.Joints.b2MouseJoint;
	import Box2D.Dynamics.Joints.b2MouseJointDef;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2DebugDraw;
	import Box2D.Dynamics.b2World;
       import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
    public class TestBox2D extends Sprite
	{
		//private static const GRAVITY
		private static const ITERATIONS:int = 10;
		private static const PIXELS_PER_METER:int = 30;
		private static const TIME_STEP:Number = 1 / 30;
		
		private var mouseJoint:b2MouseJoint;
		
		private var world:b2World;
		private var worldMouseX:Number;
		private var worldMouseY:Number;
		
		public var mousePVec:b2Vec2 = new b2Vec2();
		public var bounds:b2AABB = new b2AABB()
		public var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
		
		public function TestBox2D()
		{
			//REAL WORLD BOUNDARIES OF PHYSICS WORLD
			var bounds:b2AABB = new b2AABB();
			bounds.lowerBound.Set(-100.0, -100.0);
			bounds.upperBound.Set(100.0, 100.0);
			var gravity:b2Vec2 = new b2Vec2(0.0,10.0);
			this.world = new b2World(bounds, gravity, true);
			
			//DEBUG DRAW
			var debugDraw:b2DebugDraw = new b2DebugDraw();
			var debugSprite:Sprite = new Sprite();
			addChild(debugSprite);
			debugDraw.m_sprite = debugSprite;
			debugDraw.m_drawScale = 30;
			debugDraw.m_fillAlpha = 0.5;
			debugDraw.m_lineThickness = 1;
			debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
			this.world.SetDebugDraw(debugDraw);
			
			//CREATE GROUND
			this.createBody(255, 15, new Point(255, 390), 0, 0x0001);
			this.createBody(25 + Math.random() * 75, 25 + Math.random() * 75, new Point(50), 1, 0x0021);
			
			this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
			this.stage.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
			this.stage.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
		}
		
		private function onEnterFrame(e:Event):void
		{
			this.world.Step(TIME_STEP, ITERATIONS);
			
			this.worldMouseX = (this.stage.mouseX) / PIXELS_PER_METER;
			this.worldMouseY = (this.stage.mouseY) / PIXELS_PER_METER;
			
			if (this.mouseJoint)
			{
				var p2:b2Vec2 = new b2Vec2(this.worldMouseX, this.worldMouseY);
				this.mouseJoint.SetTarget(p2);
			}
			
			for (var bb:b2Body = this.world.m_bodyList; bb; bb = bb.m_next) {
				if (bb.m_userData is Sprite) {
					bb.m_userData.x = bb.GetPosition().x * PIXELS_PER_METER;
					bb.m_userData.y = bb.GetPosition().y * PIXELS_PER_METER;
					bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
				}
			}
		}
		
		private function onMouseDown(event:Event):void
		{
			var body:b2Body = GetBodyAtMouse();
			if (body)
			{
				//KICK AROUND
				//body.ApplyImpulse(new b2Vec2(0.0, -80.0), body.GetWorldCenter());
				//body.ApplyTorque(450);
				
				//DRAG AROUND
				var md:b2MouseJointDef = new b2MouseJointDef();
				md.body1 = this.world.m_groundBody;
				md.body2 = body;
				md.target.Set(this.worldMouseX, this.worldMouseY);
				md.maxForce = 30000.0 * body.m_mass;
				md.timeStep = TIME_STEP;
				this.mouseJoint = this.world.CreateJoint(md) as b2MouseJoint;
				body.WakeUp();
			}
			
			this.createBody(25 + Math.random() * 75, 25 + Math.random() * 75, new Point(Math.random() * this.stage.stageWidth), 1, 0x0002, 0x0001);
		}
		
		private function onMouseUp(event:Event):void
		{
			if (this.mouseJoint)
			{
				this.world.DestroyJoint(this.mouseJoint);
				this.mouseJoint = null;
			}
		}
		
		private function createBody(width:Number, height:Number, position:Point, density:Number = 1, category:Number = 1, mask:Number = 0xFFFF):void
		{
			var body:b2Body;
			var bodyDef:b2BodyDef;
			var polygonDef:b2PolygonDef;
			bodyDef = new b2BodyDef();
			bodyDef.position.Set(position.x / PIXELS_PER_METER, position.y / PIXELS_PER_METER);
			polygonDef = new b2PolygonDef();
			polygonDef.SetAsBox(width / PIXELS_PER_METER, height / PIXELS_PER_METER);
			polygonDef.friction = 0.3;
			polygonDef.density = density;
			polygonDef.filter.categoryBits = category;
			polygonDef.filter.maskBits = mask;
			//bodyDef.userData = this.createSprite();
			body = this.world.CreateBody(bodyDef);
			body.CreateShape(polygonDef);
			body.SetMassFromShapes();
		}
		
		private function createSprite():Sprite
		{
			var sprite:Sprite =  new Sprite();
			sprite.graphics.beginFill(0xFFFFFF * Math.random());
			sprite.graphics.drawRect(-90, -45, 180, 90);
			this.addChild(sprite);
			
			return sprite;
		}
		
		public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body
		{
			this.worldMouseX = (this.stage.mouseX) / PIXELS_PER_METER;
			this.worldMouseY = (this.stage.mouseY) / PIXELS_PER_METER;
			mousePVec.Set(this.worldMouseX, this.worldMouseY);
			var bounds:b2AABB = new b2AABB();
			bounds.lowerBound.Set(this.worldMouseX - 0.001, this.worldMouseY - 0.001);
			bounds.upperBound.Set(this.worldMouseX + 0.001, this.worldMouseY + 0.001);
			var k_maxCount:int = 10;
			var shapes:Array = new Array();
			var count:int = this.world.Query(bounds, shapes, k_maxCount);
			var body:b2Body = null;
			for (var i:int = 0; i < count; ++i) {
				if (shapes[i].m_body.IsStatic() == false || includeStatic) {
					var tShape:b2Shape = shapes[i] as b2Shape;
					var inside:Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec);
					if (inside) {
						body = tShape.m_body;
						break;
					}
				}
			}
			return body;
		}

	}
}