通常我们制作游戏时不可能使用Box2D提供的默认调试显示对象,我们需要创建个性化的外观,如果汽车、房子等等。那么如何把这些外观附加到刚体上面呢?这就是此教程的重点。
创建一个刚体外观,我们两步:
1. 将外观显示对象附加到刚体的刚体定义的userData属性
2. 将userData的x, y, rotation与刚体实现同步
在上一个教程的基础上,修改createBall()方法,添加显示对象Ball(自定义显示对象)
private function createBall():void
{
for(var i:int = 0; i < 10; i++)
{
var ballDef:b2BodyDef = new b2BodyDef();
ballDef.type = b2Body.b2_dynamicBody;
var radius:Number = 10+Math.random()*20;
var circleShape:b2CircleShape = new b2CircleShape(radius/PIXEL_TO_METER);
var ballFixtureDef:b2FixtureDef = new b2FixtureDef();
ballFixtureDef.shape = circleShape;
ballFixtureDef.density = 1.0;
ballFixtureDef.restitution = 1.0;
ballFixtureDef.friction = 0.5;
ballDef.position.Set(stage.stageWidth/2/PIXEL_TO_METER,20/PIXEL_TO_METER);
//为每一个球创建一个相同大小的显示对象外观
var ballSprite:Ball = new Ball(radius,i+"");
//将显示对象存入刚体定义的userData树形
ballDef.userData = ballSprite;
//添加到容器中
addChild(ballSprite);
var ball:b2Body = world.CreateBody(ballDef);
ball.CreateFixture(ballFixtureDef);
}
}
实现显示外观与刚体的同步
private function aysncSprite():void
{
//遍历物理世界的所有刚体,此处为何如此遍历请参考Manual
//如果你已经给外观指定了变量,就不用遍历,直接调用变量
var body:b2Body = world.GetBodyList();
while(body!=null)
{
if(body.GetDefinition().userData is Sprite)
{
var ballSprite:Sprite = body.GetDefinition().userData as Sprite;
ballSprite.x = body.GetPosition().x * PIXEL_TO_METER;
ballSprite.y = body.GetPosition().y * PIXEL_TO_METER;
ballSprite.rotation = body.GetAngle() * (180 / Math.PI);
}
body = body.GetNext();
}
}
在handleEnterframe方法中实现同步,并取消Box2D的debug绘制。
private function handleEnterFrame(evt:Event):void
{
//更新鼠标位置
UpdateMouseWorld();
//不断调用鼠标拖动方法
mouseDrag();
var timeStep:Number = 1/30;
var velocityInterations:int = 10;
var positionIterations:int = 10;
world.Step(timeStep,velocityInterations,positionIterations);
//同步显示对象和刚体
aysncSprite();
//在2.1版本清除力,以提高效率
world.ClearForces();
//绘制
// world.DrawDebugData();
}