因为时间比较急,故此只能快速寻找一些资料看。发现使用box2D 2.1a 版本确实和之前发生兼容性问题,实现拖拽真不容易,完全看不懂。先记录一下其他人写的拖拽部分代码。这部分代码加入到HelloWorld 里面去。多少有点长了 不容易学习。
public class HelloWorld extends Sprite
{
//程序入口,创建一个世界
private var world:b2World = new b2World(new b2Vec2(0,10.0),true);
private var worldScale:int = 30;//30像素=1米
private static const vesion:String="box2d for 2.1a";
private var mouseJoint:b2MouseJoint;
public function HelloWorld()
{
debugDraw();
drawBox(250,300,500,50,false);
drawBox(250,100,100,100,true);
drawCircle(100,100,50,true);
addEventListener(Event.ENTER_FRAME, updateHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
}
//绘制一个矩形
private function drawBox(x:Number,y:Number,width:Number,height:Number,isDynamic:Boolean):void
{
var bodyDef:b2BodyDef= new b2BodyDef();
bodyDef.position.Set(x/worldScale, y/worldScale);
if (isDynamic)
{
bodyDef.type = b2Body.b2_dynamicBody;
}
var box:b2PolygonShape = new b2PolygonShape();
box.SetAsBox(width/2/worldScale, height/2/worldScale);
var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.shape = box;
var body:b2Body = world.CreateBody(bodyDef);
body.CreateFixture(fixtureDef);
}
//绘制一个圆
private function drawCircle(x:Number,y:Number,radius:Number,isDynamic:Boolean):void
{
var bodyDef:b2BodyDef= new b2BodyDef();
bodyDef.position.Set(x/worldScale, y/worldScale);
if (isDynamic)
{
bodyDef.type = b2Body.b2_dynamicBody;
}
var circle:b2CircleShape=new b2CircleShape(radius/worldScale);
var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.shape = circle;
var body:b2Body = world.CreateBody(bodyDef);
body.CreateFixture(fixtureDef);
}
private function debugDraw():void
{
var _debugDraw:b2DebugDraw=new b2DebugDraw();
var sprite:Sprite=new Sprite();
addChild(sprite);
_debugDraw.SetSprite(sprite);
_debugDraw.SetDrawScale(worldScale);
_debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
world.SetDebugDraw(_debugDraw);
}
//交互的过程由四个步骤完成:
//第一步:获取鼠标单击处的刚体。
//第二步:创建鼠标关节。
//第三步:控制鼠标关节。
//第四步:销毁鼠标关节。
private function getBodyAtMouse(includeStatic:Boolean=false):b2Body
{
var mouseXWorldPhys:Number = (mouseX)/worldScale;
var mouseYWorldPhys:Number = (mouseY)/worldScale;
var mousePVec:b2Vec2 = new b2Vec2();
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);
var body:b2Body = null;
function query(fix:b2Fixture):Boolean {
var shape:b2Shape = b2Fixture(fix).GetShape();
if (fix.GetBody().GetType() != b2Body.b2_staticBody || includeStatic) {
var inside:Boolean = b2Shape(shape).TestPoint(fix.GetBody().GetTransform(), mousePVec);
if (inside) {
body = fix.GetBody();
return false;
}
}
return true;
}
world.QueryAABB(query, aabb);
return body;
}
private function onMouseDownHandler(event:MouseEvent):void
{
var mouseJoinDef:b2MouseJointDef;
var body:b2Body = this.getBodyAtMouse();
if (body)
{
mouseJoinDef = new b2MouseJointDef();
mouseJoinDef.bodyA = world.GetGroundBody();
mouseJoinDef.bodyB = body;
mouseJoinDef.target.Set((mouseX / worldScale), (mouseY / worldScale));
mouseJoinDef.maxForce = 10000;
this.mouseJoint = (world.CreateJoint(mouseJoinDef) as b2MouseJoint);
}
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
private function onMouseUpHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
if (this.mouseJoint)
{
world.DestroyJoint(this.mouseJoint);
this.mouseJoint = null;
}
}
private function updateHandler(event:Event):void
{
world.Step(1/30,10,10);
world.ClearForces();
world.DrawDebugData();
//拖拽部分
if (mouseJoint) {
var mouseXWorldPhys:Number = mouseX / worldScale;
var mouseYWorldPhys:Number = mouseY / worldScale;
var p2:b2Vec2=new b2Vec2(mouseXWorldPhys,mouseYWorldPhys);
mouseJoint.SetTarget(p2);
}
}
}
}
其中这几部分是拖拽的,是由一些网友书写。借用一下。
var body:b2Body = null;
function query(fix:b2Fixture):Boolean {
var shape:b2Shape = b2Fixture(fix).GetShape();
if (fix.GetBody().GetType() != b2Body.b2_staticBody || includeStatic) {
var inside:Boolean = b2Shape(shape).TestPoint(fix.GetBody().GetTransform(), mousePVec);
if (inside) {
body = fix.GetBody();
return false;
}
}
return true;
}
world.QueryAABB(query, aabb);
return body;
}
private function onMouseDownHandler(event:MouseEvent):void
{
var mouseJoinDef:b2MouseJointDef;
var body:b2Body = this.getBodyAtMouse();
if (body)
{
mouseJoinDef = new b2MouseJointDef();
mouseJoinDef.bodyA = world.GetGroundBody();
mouseJoinDef.bodyB = body;
mouseJoinDef.target.Set((mouseX / worldScale), (mouseY / worldScale));
mouseJoinDef.maxForce = 10000;
this.mouseJoint = (world.CreateJoint(mouseJoinDef) as b2MouseJoint);
}
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
}
private function onMouseUpHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
if (this.mouseJoint)
{
world.DestroyJoint(this.mouseJoint);
this.mouseJoint = null;
}
}
通过这些设置 可以实现拖拽,同时也有一些人 封装了一个类对其方便调用。不妨可以修改一下
注意:2.1a版本改过命名。
过去版本:
mouseJoinDef.body1 = world.GetGroundBody();
mouseJoinDef.body2 = body;
改成了bodyA 和bodyB 属性
mouseJoinDef.bodyA = world.GetGroundBody();
mouseJoinDef.bodyB = body;
有部分属性取消了。在编译过程如果使用低版本的和高级 版本不一样了。