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, 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;
}
}