1.绘制皮肤
用flash cs新建fla文件,注意在绘制它们的时候要将注册点设置在中心,然后发布成swc,这里我提供我的皮肤,
主要用到了里面的两个元件FloorAsset和IconAsset,分别是地面和头像的皮肤.
2.引入皮肤
先上代码
package { import Box2D.Collision.Shapes.b2polygonShape; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2FixtureDef; import Box2D.Dynamics.b2World; import flash.display.displayObject; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.textformat; [SWF(width="410",height="480")] public class Skin extends Sprite { private var stageWidth:Number = 410; //舞台宽度 private var stageHeight:Number = 480; //舞台高度 private var backgroundColor:uint = 0x333333; //背景色 private var world:b2World; //Box2D世界 private var worldScale:Number = 30; //一米等于30像素 private var timestep:Number = 1 / 30; //时间步,世界将在每一个时间步被更新 //只是定义了时间步还不够。在每一步,每一个物理实体(physic entity)根据作用 //于自身的作用力来更新(不包括睡眠状态)。处理这项任务的算法叫约束解算器 //(constraint solver)。它是基于循环每一个约束然后解算来进行的,一次一个。 private var velIterations:int = 10; //速率约束解算器 private var posIterations:int = 10; //位置约束解算器 public function Skin() { drawBackground(); initWorld(); createTip(); createFloor(); addEventListener(Event.ENTER_FRAME,onUpdate); stage.addEventListener(MouseEvent.CLICK,onStageClick); } private function onStageClick(event:MouseEvent):void { createIcon(mouseX,mouseY); } private function createTip():void { var tip:TextField = new TextField(); var format:textformat = new textformat(); format.color = 0xFFFFFF; tip.autoSize = TextFieldAutoSize.LEFT; tip.defaulttextformat = format; tip.text = "点击,创建头像"; addChild(tip); tip.x = (stageWidth - tip.width) / 2; } private function createIcon(x:Number,y:Number):void { var iconAsset:displayObject = new IconAsset(); var bodyDef:b2BodyDef = new b2BodyDef(); //刚体定义 bodyDef.type = b2Body.b2_dynamicBody; //动态刚体 //设置刚体坐标,Box2D坐标用米来表示,注册点是中心点 bodyDef.position.Set(x/worldScale,y/worldScale); bodyDef.userData = new Object(); bodyDef.userData.asset = iconAsset; addChild(iconAsset); var polygonShape:b2polygonShape = new b2polygonShape(); //创建多边形 polygonShape.SetAsBox(iconAsset.width/2/worldScale,iconAsset.height/2/worldScale); //轴对称的矩形,半宽长和半高长 var fixtureDef:b2FixtureDef = new b2FixtureDef(); //夹具(fixture)用于将形状绑定到刚体上 fixtureDef.density = 1; //密度 fixtureDef.restitution = 0.1; //弹性系数 fixtureDef.friction = 0.1; //摩擦系数 fixtureDef.shape = polygonShape; var theRect:b2Body = world.CreateBody(bodyDef); theRect.CreateFixture(fixtureDef); iconAsset.x = theRect.GetPosition().x * worldScale; iconAsset.y = theRect.GetPosition().y * worldScale; } private function initWorld():void { var gravity:b2Vec2 = new b2Vec2(0,9.81); //重力 //世界中的刚体静止时,可以允许他们进入睡眠状态,睡眠的刚体无需模拟 var sleep:Boolean = true; world = new b2World(gravity,sleep); } //创建地面 private function createFloor():void { var floorAsset:displayObject = new FloorAsset(); //地面皮肤 var bodyDef:b2BodyDef = new b2BodyDef(); //刚体定义 bodyDef.type = b2Body.b2_staticBody; //刚体类型为静态 bodyDef.userData = new Object(); bodyDef.userData.asset = floorAsset; //设置刚体坐标,Box2D坐标用米来表示,注册点是中心 bodyDef.position.Set(floorAsset.width/2/worldScale,(stageHeight - floorAsset.height/2)/worldScale); var polygonShape:b2polygonShape = new b2polygonShape(); //创建多边形 polygonShape.SetAsBox(floorAsset.width/2/worldScale,floorAsset.height/2/worldScale);//轴对称的矩形,半宽长和半高长 var fixtureDef:b2FixtureDef = new b2FixtureDef(); //夹具(fixture)用于将形状绑定到刚体上 fixtureDef.density = 1; //密度 fixtureDef.restitution = 0.3; //弹性系数 fixtureDef.friction = 0.1; //摩擦系数 fixtureDef.shape = polygonShape; var theFloorBody:b2Body = world.CreateBody(bodyDef); //创建刚体 theFloorBody.CreateFixture(fixtureDef); addChild(floorAsset); floorAsset.x = theFloorBody.GetPosition().x * worldScale; floorAsset.y = theFloorBody.GetPosition().y * worldScale; } private function onUpdate(e:Event):void { world.Step(timestep,velIterations,posIterations); world.ClearForces(); for (var body:b2Body = world.GetBodyList(); body; body = body.GetNext()) { if(body.GetUserData()) { body.GetUserData().asset.x = body.GetPosition().x * worldScale; body.GetUserData().asset.y = body.GetPosition().y * worldScale; body.GetUserData().asset.rotation = body.GetAngle() * 180 / Math.PI; //弧度转为度 } } } private function drawBackground():void { graphics.beginFill(backgroundColor); graphics.drawRect(0,stageWidth,stageHeight); graphics.endFill(); } } }
用flash builder新建项目,新建Skin.as文件,然后将以上代码粘贴到Skin.as文件中
引入skin.swc,然后运行
3.关键代码
为刚体添加皮肤,主要是bodyDef.userData
var iconAsset:displayObject = new IconAsset();
bodyDef.userData = new Object();
bodyDef.userData.asset = iconAsset;
addChild(iconAsset);
同步皮肤元件与刚体的位置和旋转角度
for (var body:b2Body = world.GetBodyList(); body; body = body.GetNext()) {
if(body.GetUserData()) {
body.GetUserData().asset.x = body.GetPosition().x * worldScale;
body.GetUserData().asset.y = body.GetPosition().y * worldScale;
body.GetUserData().asset.rotation = body.GetAngle() * 180 / Math.PI;
}
}