自定义刚体与拖动
调用b2PolygonDef的setAsBox函数传入一个半宽和半高,即可以创建一个矩形刚体,设置b2CircleDef的radius属性,即可以创建一个圆形的刚体,如果现在要创建一个五边形,六边形的刚体呢,box2d并没有提供这样的方法来创建。
利用b2PolygonDef的两个属性vertexCount和vertices,可以创建自定义刚体。
vertexCount:刚体的顶点数。
vertices:一个数组,用来保存刚体的所有定点。
package
{
import Box2D.Collision.Shapes.b2PolygonDef;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.Joints.b2MouseJoint;
import Box2D.Dynamics.Joints.b2MouseJointDef;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import myClass.box2d.PhyOption;
import myClass.box2d.Floor;
import myClass.box2d.Wall;
/**
* ...
* @author ywxgod
*/
[SWF(backgroundColor="0x333333",frameRate="30")]
public class CustomBody extends Sprite
{
private var _world:b2World;
private var _mouseJoint:b2MouseJoint;
public function CustomBody()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
_world = PhyOption.getInstance().world;
new Floor(new MyFloor(), this);
new Wall(new MyFloor(), this, Wall.LEFT);
new Wall(new MyFloor(), this,Wall.RIGHT);
createBodies();
showDebug();
addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
private function setConvexVertex(shapeDef:b2PolygonDef,n:int,radius:Number):void
{
shapeDef.vertexCount = n;
var angle:Number = Math.PI * 2 / n;
var radius:Number = radius / PhyOption.PHYSCALE;
for (var i:int = 0; i < n;i++ )
{
var dx:Number = radius * Math.cos(angle * i);
var dy:Number = radius * Math.sin(angle * i);
shapeDef.vertices[i].Set(dx,dy);
}
shapeDef.friction = 0.3;
shapeDef.restitution = 0.3;
shapeDef.density = 2;
}
private function setRandomInt(a:int,b:int):int
{
return a + Math.floor(Math.random() * (b - a + 1));
}
private function createBodies():void
{
for (var i:int = 3; i <= 7;i++ )
{
var xpos:Number = 275 + setRandomInt( -20, 20);
var ypos:Number = 0;
var radius:Number = 30 + setRandomInt( -20, 20);
createBody(xpos,ypos,i,radius);
}
}
private function createBody(xpos:Number,ypos:Number,vertexCount:int,radius:Number):void
{
var boxShapeDef:b2PolygonDef = new b2PolygonDef();
setConvexVertex(boxShapeDef,vertexCount,radius);
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.angle = Math.random() * 360;
bodyDef.position.Set(xpos/ PhyOption.PHYSCALE, ypos/PhyOption.PHYSCALE);
var body:b2Body = _world.CreateBody(bodyDef);
body.CreateShape(boxShapeDef);
body.SetMassFromShapes();
}
private function showDebug():void
{
var sp:Sprite = new Sprite();
this.addChild(sp);
var dbg:b2DebugDraw = new b2DebugDraw();
dbg.m_sprite = sp;
dbg.m_alpha = 0.5;
dbg.m_drawScale = PhyOption.PHYSCALE;
dbg.m_fillAlpha = 0.5;
dbg.m_drawFlags = b2DebugDraw.e_shapeBit;
dbg.m_lineThickness = 1;
_world.SetDebugDraw(dbg);
}
private function onFrame(e:Event):void
{
PhyOption.getInstance().update();
if (_mouseJoint)
{
_mouseJoint.SetTarget(new b2Vec2(stage.mouseX/PhyOption.PHYSCALE,stage.mouseY/PhyOption.PHYSCALE));
}
}
private function onDown(e:MouseEvent):void
{
var body:b2Body = PhyOption.getInstance().GetBodyAtMouse(this.stage);
if (body)
{
var mouseJointDef:b2MouseJointDef = new b2MouseJointDef();
mouseJointDef.body1 = _world.GetGroundBody();
mouseJointDef.body2 = body;
mouseJointDef.maxForce = 40000;
mouseJointDef.timeStep = PhyOption.STEP;
mouseJointDef.target.Set(stage.mouseX / PhyOption.PHYSCALE, stage.mouseY / PhyOption.PHYSCALE);
_mouseJoint = _world.CreateJoint(mouseJointDef) as b2MouseJoint;
}
}
private function onUp(e:MouseEvent):void
{
if (_mouseJoint)
{
_world.DestroyJoint(_mouseJoint);
_mouseJoint = null;
}
}
}
}
39-42行:PhyOption,Floor,Wall都是自定义类,分别用来初始化b2world,创建地面,墙壁等。
52-66行:函数setConvexVertex创建圆内切多边形,box2d中只对凸多边形起作用,凹多边形是box2d无法处理的。
73-83行:创建3,4,5。。。7边形。奇怪的是,如果创建九边形,就会报错,即:循环i从3到8没问题,一旦循环到9就会报错:
TypeError: Error #1010: 术语尚未定义,并且无任何属性。
at CustomBody/setConvexVertex()
at CustomBody/createBody()
at CustomBody/createBodies()
at CustomBody/init()
at CustomBody()
此处我用的flashDevelop创建的一个Flash IDE Project,用的是FlashCS4编译运行,不知道这个是不是一个bug呢?有遇到过此类问题的朋友还请不吝赐教。
97-109行:显示box2d的debug模式。
122行:寻找鼠标点击处的刚体。
125-131行:创建一个mouseJoint,用来拖动刚体。创建mouseJoint跟刚体一样,先要创建mouseJointDef的各个参数。
body1:值为_world.GetGroundBody(),_world.GetGroundBody()具体表示的是哪一个刚体,本人还未明白,看源代码注释不是很清楚,如果您明白还请不吝赐教啊!
body2:鼠标点击处的刚体。
maxForce:拖动刚体时铰链给刚体的最大力,box2d会根据这个力来计算刚体被拖动的最大速度及位移,使得刚体始终处于鼠标的控制之下,实际这里的拖动,并不像flash中拖动一个显示对象用startDrag()或者设置对象的坐标为鼠标的坐标,box2d中考虑了更多复杂的运动参数,有加速度,质量,动量,冲量等。
timeStep:box2d模拟屋里世界的时间片,一般取swf文件帧频的倒数。
target:目标位置,设置为鼠标位置。在EnterFrame事件中更新目标。
E-mail:给我发邮件
出处:http://ywxgod.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号