天天看點

flash與實體引擎:拖拽

   因為時間比較急,故此隻能快速尋找一些資料看。發現使用box2D 2.1a 版本确實和之前發生相容性問題,實作拖拽真不容易,完全看不懂。先記錄一下其他人寫的拖拽部分代碼。這部分代碼加入到HelloWorld 裡面去。多少有點長了 不容易學習。

package

{

import flash.display.Sprite;

import flash.events.*;

import Box2D.Dynamics.*;

import Box2D.Collision.*;

import Box2D.Collision.Shapes.*;

import Box2D.Common.Math.*;

import Box2D.Dynamics.Joints.*;

import Box2D.Dynamics.Controllers.*;

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);

}

}

}

}

其中這幾部分是拖拽的,是由一些網友書寫。借用一下。

//互動的過程由四個步驟完成:

//第一步:擷取滑鼠單擊處的剛體。

//第二步:建立滑鼠關節。

//第三步:控制滑鼠關節。

//第四步:銷毀滑鼠關節。

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;

}

}

//拖拽部分

if (mouseJoint) {

var mouseXWorldPhys:Number = mouseX / worldScale;

var mouseYWorldPhys:Number = mouseY / worldScale;

var p2:b2Vec2=new b2Vec2(mouseXWorldPhys,mouseYWorldPhys);

mouseJoint.SetTarget(p2);

}

通過這些設定 可以實作拖拽,同時也有一些人 封裝了一個類對其友善調用。不妨可以修改一下

注意:2.1a版本改過命名。

 過去版本:

mouseJoinDef.body1 =  world.GetGroundBody();

mouseJoinDef.body2 = body;

改成了bodyA 和bodyB 屬性

mouseJoinDef.bodyA =  world.GetGroundBody();

mouseJoinDef.bodyB = body;

有部分屬性取消了。在編譯過程如果使用低版本的和進階 版本不一樣了。

繼續閱讀