每个Box2D程序都将从一个世界对象的创建开始。他是管理对象以及模拟的中心。
Code
private function initWorld():void
{
//定义世界包围盒
var worldAABB:b2AABB=new b2AABB();
worldAABB.lowerBound.Set(-100,-100);
worldAABB.upperBound.Set(600,600);
//定义重力
var gravity:b2Vec2=new b2Vec2(0,-10);
//定义允许物体休眠
var doSleep:Boolean=true;
this.world=new b2World(worldAABB,gravity,doSleep);
}
创建世界对象b2World,
(1)首先应当创建包围和盒对象b2AABB。他的大小是越大越好。
因为当刚体碰到包围盒的边缘的时候他会停止模拟。
(2)创建世界中的重力场。他是一个2维的适量b2Vec2。
(3)当物体停止移动的时候,让物体停止模拟。节约资源doSleep。
以上这3个的确定都是初始化world对象所必须的。到此就创建了一个有一定的大小以及一定的重力场的空间,有了就可以往里面装东西了。
创建刚体b2Body,
(1)刚体的是由世界对象来创建的
var body:b2Body=this.world.CreateBody(bodyDef);
其中的参数bodyDef是b2BodyDef创建的,是对body的defination.
var bodyDef:b2BodyDef=new b2BodyDef();
bodyDef.position.Set(0,4);
他主要是用于初始化刚体在世界空间里的一些属性。包括位置(position)、质量(mass)、旋转角度(angle)等。
现在我们已经创建了一个刚体,并确定了他在世界空间当中的位置。物体到底是什么样的,以及他的物理属性怎么样是我么马上就要创建的。
(2)给物体定义形状以及物理材质
body.CreateShape(shapeDef);
其中的初始参数shapeDef是b2ShapeDef
1
var shapeDef:b2Polygnotallow=new b2PolygonDef();//定义形状为多边形
2
shapeDef.SetAsBox(3,3);//将多边形设为矩形
3
shapeDef.density=1.0;//定义密度
4
shapeDef.frictinotallow=0.3;//定义摩擦力
b2PolygonDef是继承自b2ShapeDef
public class b2PolygonDef extends b2ShapeDef
除了b2PolygonDef外还有b2CircleDef。
到现在我们的刚体依然是没的外观的,对其定义的shapeDef也只是对其封装了一些特殊的属性而已。
实际上定义刚体外观的是bodyDef(shapeDef也有这个属性)的userDate属性,他是*类型的。任何类型的对象都可以给他。我们现在需要用它来定义外观(形状)就将形状类或影片类的引用传给他就可以了。同时需要将userData加入到舞台的显示列表当中。
bodyDef.userData = new PhysCircle();
bodyDef.userData.width = rX * 2 * 30;
bodyDef.userData.height = rX * 2 * 30;
其中的physCircle是sharp类的自定义类。
来自官方的helloWorld源码:
Code
1
package Application
2
{
3
4
import flash.display.Sprite;
5
import flash.events.Event;
6
// Classes used in this example
7
import Box2D.Dynamics.*;
8
import Box2D.Collision.*;
9
import Box2D.Collision.Shapes.*;
10
import Box2D.Common.Math.*;
11
12
public class HelloWorld extends Sprite
{
13
14
public function HelloWorld()
{
15
16
17
18
// Add event for main loop
19
addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
20
21
22
23
// Creat world AABB
24
var worldAABB:b2AABB = new b2AABB();
25
worldAABB.lowerBound.Set(-100.0, -100.0);
26
worldAABB.upperBound.Set(100.0, 100.0);
27
28
// Define the gravity vector
29
var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
30
31
// Allow bodies to sleep
32
var doSleep:Boolean = true;
33
34
// Construct a world object
35
m_world = new b2World(worldAABB, gravity, doSleep);
36
37
// set debug draw
38
/**//*var dbgDraw:b2DebugDraw = new b2DebugDraw();
39
var dbgSprite:Sprite = new Sprite();
40
addChild(dbgSprite);
41
dbgDraw.m_sprite = dbgSprite;
42
dbgDraw.m_drawScale = 30.0;
43
dbgDraw.m_fillAlpha = 0.0;
44
dbgDraw.m_lineThickness = 1.0;
45
dbgDraw.m_drawFlags = 0xFFFFFFFF;
46
m_world.SetDebugDraw(dbgDraw);*/
47
48
49
50
// Vars used to create bodies
51
var body:b2Body;
52
var bodyDef:b2BodyDef;
53
var boxDef:b2PolygonDef;
54
var circleDef:b2CircleDef;
55
56
57
58
// Add ground body
59
bodyDef = new b2BodyDef();
60
//bodyDef.position.Set(15, 19);
61
bodyDef.position.Set(10, 12);
62
//bodyDef.angle = 0.1;
63
boxDef = new b2PolygonDef();
64
boxDef.SetAsBox(30, 3);
65
boxDef.friction = 0.3;
66
boxDef.density = 0; // static bodies require zero density
67
/**//*circleDef = new b2CircleDef();
68
circleDef.radius = 10;
69
circleDef.restitution = 0.2*/
70
// Add sprite to body userData
71
bodyDef.userData = new PhysGround();
72
//bodyDef.userData = new PhysCircle();
73
bodyDef.userData.width = 30 * 2 * 30;
74
bodyDef.userData.height = 30 * 2 * 3;
75
addChild(bodyDef.userData);
76
body = m_world.CreateBody(bodyDef);
77
body.CreateShape(boxDef);
78
//body.CreateShape(circleDef);
79
body.SetMassFromShapes();
80
81
// Add some objects
82
for (var i:int = 1; i < 10; i++)
{
83
bodyDef = new b2BodyDef();
84
bodyDef.position.x = Math.random() * 15 + 5;
85
bodyDef.position.y = Math.random() * 10;
86
var rX:Number = Math.random() + 0.5;
87
var rY:Number = Math.random() + 0.5;
88
// Box
89
if (Math.random() < 0.5)
{
90
boxDef = new b2PolygonDef();
91
boxDef.SetAsBox(rX, rY);
92
boxDef.density = 1.0;
93
boxDef.friction = 0.5;
94
boxDef.restitution = 0.2;
95
bodyDef.userData = new PhysBox();
96
bodyDef.userData.width = rX * 2 * 30;
97
bodyDef.userData.height = rY * 2 * 30;
98
body = m_world.CreateBody(bodyDef);
99
body.CreateShape(boxDef);
100
}
101
// Circle
102
else
{
103
circleDef = new b2CircleDef();
104
circleDef.radius = rX;
105
circleDef.density = 1.0;
106
circleDef.friction = 0.5;
107
circleDef.restitution = 0.2
108
bodyDef.userData = new PhysCircle();
109
bodyDef.userData.width = rX * 2 * 30;
110
bodyDef.userData.height = rX * 2 * 30;
111
body = m_world.CreateBody(bodyDef);
112
body.CreateShape(circleDef);
113
}
114
body.SetMassFromShapes();
115
addChild(bodyDef.userData);
116
}
117
118
}
119
120
public function Update(e:Event):void
{
121
122
m_world.Step(m_timeStep, m_iterations);
123
124
// Go through body list and update sprite positions/rotations
125
for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next)
{
126
if (bb.m_userData is Sprite)
{
127
bb.m_userData.x = bb.GetPosition().x * 30;
128
bb.m_userData.y = bb.GetPosition().y * 30;
129
bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
130
}
131
}
132
133
}
134
135
public var m_world:b2World;
136
public var m_iterations:int = 10;
137
public var m_timeStep:Number = 1.0/30.0;
138
139
}
140
141
}
其中的userData的对象都是在flash中定义影片剪辑导出类。