Testing how to use DistanceJoint.
package {
import Box2D.Collision.b2AABB;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.Joints.*;
import Box2D.Dynamics.b2World;
import General.Input;
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite {
private const DRAW_SCALE:uint = 100;
private var world:b2World;
private var fps:int;
private var wallDef:Array = [[2.5, -1, 2.5, 1],
[6, 2.5, 1, 2.5],
[2.5, 6, 2.5, 1],
[-1, 2.5, 1, 2.5]
];
private var sbdDef:Array = [[1, 0.5, 0.1, 0.05],
[1.25, 0.5, 0.1, 0.05],
[1.5, 0.5, 0.1, 0.05],
[1.75, 0.5, 0.1, 0.05],
[2, 0.5, 0.1, 0.05],
[2.25, 0.5, 0.1, 0.05],
[2.5, 0.5, 0.1, 0.05],
[2.75, 0.5, 0.1, 0.05],
[3, 0.5, 0.1, 0.05],
[3.25, 0.5, 0.1, 0.05],
[3.5, 0.5, 0.1, 0.05],
[3.75, 0.5, 0.1, 0.05],
[4, 0.5, 0.1, 0.05]];
private var stageSp:Sprite;
private var sbds:Array = [];
public function Main():void {
fps = stage.frameRate;
addEventListener(Event.ENTER_FRAME, h_enterFrame);
addChild(stageSp = new Sprite());
init();
}
private function init():void {
input = new Input(this);
// create the world
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100, -100);
worldAABB.upperBound.Set(100, 100);
var gravity:b2Vec2 = new b2Vec2(0,0);
world = new b2World(worldAABB,gravity,true);
// * entities *
var bodyDef:b2BodyDef;
var shapeDef:b2PolygonDef;
var body:b2Body;
var sp:Sprite;
var i:uint;
// create walls
for (i = 0; i < wallDef.length; i ++) {
bodyDef = new b2BodyDef();
bodyDef.position.Set(wallDef[i][0],wallDef[i][1]);
shapeDef = new b2PolygonDef();
shapeDef.SetAsBox(wallDef[i][2],wallDef[i][3]);
body = world.CreateBody(bodyDef);
body.CreateShape(shapeDef);
}
// create body
for (i = 0; i < sbdDef.length; i ++) {
bodyDef = new b2BodyDef();
bodyDef.position.Set(sbdDef[i][0],sbdDef[i][1]);
shapeDef = new b2PolygonDef();
shapeDef.SetAsBox(sbdDef[i][2],sbdDef[i][3]);
shapeDef.density = 1;
shapeDef.restitution = 0.05;
body = world.CreateBody(bodyDef);
body.CreateShape(shapeDef);
body.SetMassFromShapes();
sbds.push(body);
}
// initial velocity
sbds[0].SetLinearVelocity(new b2Vec2(0,10));
// create joints
var djDef:b2DistanceJointDef;
for (i = 1; i < sbds.length; i ++) {
djDef = new b2DistanceJointDef();
djDef.Initialize(sbds[i-1], sbds[i], sbds[i-1].GetPosition(), sbds[i].GetPosition());
djDef.collideConnected = true;
world.CreateJoint(djDef);
}
// debug draw
var debugDraw:b2DebugDraw = new b2DebugDraw();
debugDraw.m_sprite = stageSp;
debugDraw.m_drawScale = 100;
debugDraw.m_fillAlpha = 0.3;
debugDraw.m_lineThickness = 1;
debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;;
world.SetDebugDraw(debugDraw);
}
private function h_enterFrame(event:Event):void {
if (world == null) {
return;
}
// step
world.Step(1 / fps, 10);
UpdateMouseWorld();
MouseDrag();
Input.update();
}
// mouse controle
public var mouseJoint:b2MouseJoint;
private var mouseXWorldPhys:Number;
private var mouseYWorldPhys:Number;
private var mouseXWorld:Number;
private var mouseYWorld:Number;
private var input:Input;
private var mousePVec:b2Vec2 = new b2Vec2();
public function UpdateMouseWorld():void{
mouseXWorldPhys = (Input.mouseX)/DRAW_SCALE;
mouseYWorldPhys = (Input.mouseY)/DRAW_SCALE;
mouseXWorld = (Input.mouseX);
mouseYWorld = (Input.mouseY);
}
// drag
public function MouseDrag():void{
// mouse press
if (Input.mouseDown && !mouseJoint){
var body:b2Body = GetBodyAtMouse();
if (body)
{
var md:b2MouseJointDef = new b2MouseJointDef();
md.body1 = world.GetGroundBody();
md.body2 = body;
md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
md.maxForce = 300.0 * body.GetMass();
md.timeStep = 1/fps;
mouseJoint = world.CreateJoint(md) as b2MouseJoint;
body.WakeUp();
}
}
// mouse release
if (!Input.mouseDown){
if (mouseJoint)
{
world.DestroyJoint(mouseJoint);
mouseJoint = null;
}
}
// mouse move
if (mouseJoint)
{
var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
mouseJoint.SetTarget(p2);
}
}
public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body{
// Make a small box.
mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys);
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);
// Query the world for overlapping shapes.
var k_maxCount:int = 10;
var shapes:Array = new Array();
var count:int = world.Query(aabb, shapes, k_maxCount);
var body:b2Body = null;
for (var i:int = 0; i < count; ++i)
{
if (shapes[i].GetBody().IsStatic() == false || includeStatic)
{
var tShape:b2Shape = shapes[i] as b2Shape;
var inside:Boolean = tShape.TestPoint(tShape.GetBody().GetXForm(), mousePVec);
if (inside)
{
body = tShape.GetBody();
break;
}
}
}
return body;
}
}
}