Box2D物理引擎

Box2d是一個很出名的2d物理引擎,大家可以google之。Box2d有C++,flash和Java等版本。android可以直接使用java版本的Jbox2d,但因為Jbox2d的圖形渲染是使用processing庫來實現的,所以,在android中使用Jbox2d的時候,圖形渲染的工作就只能自己來寫了。因為網上關於box2d的資料真的非常的少,特別是關於圖形繪製方面

package
{
import flash.display.MovieClip;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import flash.events.Event;
import flash.display.Sprite;
import flash.events.MouseEvent;
/**
* date:2009.3.18
* BOX2D測試
* @author cwin5
*
*
* 全局的對象的構造函式作了三件事情:
* 1、一個在b2AABB類中的實例構建的坐標系統
* 2、一個定義重力的向量,這是一個b2Vec2類構建的實例。
* 3、一個布爾變數來定義對象是否"睡眠"。(如果你設定為true,對象將會睡眠)。
*
* 執行Step()函式,每一幀都會更新所有的Body在world中的位置。
*
*
* 雖然現在的world中是空的,但是你可以往裡面添加任何的球體或者盒子,以及你想到的任何形狀的東西,我們需要定義一個Body。
* 一個body體大概需要做2-4件事情:
* * * 1、定義一個形狀。
* 2、一個(x,y)的位置
* 下面的定義可選:
* 3、角度
* 4、一個預製的Sprite對象。
*
* 在Box2DFlash的例子中,你可能注意到所有的形狀都是簡單的。這是因為所有的東西在每一幀都是被線條重繪。
* 如果你想在你的遊戲或者其他的什麼中具有一些有特色的東西,你可以通過綜合形狀定義Body來製作一個Sprite
*
* 形狀的定義,我們有3種類型的形狀定義,他們都是擴展的b2ShapeDef基類。
*
* 我們先來說b2BoxDef類,這個具有4個重要的屬性:
* 1、SetAsBox(設定框線):這是一個向量,本質上說他就是一個形狀的中心坐標
* 2、Density(密度):在碰撞的等式中我們使用密度*面積=質量,密度如果是0或者null,將會是一個靜止的對象。
* 3、Friction(摩擦力):這用來計算兩個對象之間的摩擦,你可以在0.0-1.0之間調整它們。
* 4、Restitution(彈性):這是調整對象彈性程度的屬性,你可以在0.0-1.0之間調整它們。
* b2CircleDef類中有一個不同的屬性,代替SetAsBox是他的Radius(半徑)。
* b2PolyDef類具有一個頂點數組(最大是8)來代替SetAsBox和Radius。這些頂點都是b2Vec2類型的對象。
*
*/
public class Main extends MovieClip
{
public var m_world:b2World;//世界對象
public var m_iterations:int = 10;//跌代
public var m_timeStep:Number = 1.0/24.0;//時間步
public function Main()
{
//創建世界邊界
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set( -100.0, -100.0);//上限
worldAABB.upperBound.Set(100.0, 100.0);//下限
//確定重力
var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
//允許引擎睡眠
var doSleep:Boolean = true;
//構建一個世界對象
m_world = new b2World(worldAABB, gravity, doSleep); //邊界,重力,睡眠開關
//創建變數
var body:b2Body;
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
//添加地表
bodyDef = new b2BodyDef();//物體
bodyDef.position.Set(10, 12);//位置
boxDef = new b2PolygonDef();//多邊形寫義
boxDef.SetAsBox(30, 3);//設定框線
boxDef.friction = 0.3;//摩擦力
boxDef.density = 0;//密度,靜態物體需要0密度
bodyDef.userData = new PhysGround();//用戶數據,可為顯示對象,或為自己的對象
bodyDef.userData.width = 30 * 2 * 30;//寬
bodyDef.userData.height = 30 * 2 * 3;//高
addChild(bodyDef.userData);//添加至舞台
body = m_world.CreateBody(bodyDef);//創建剛體
body.CreateShape(boxDef);//創建圖形
body.SetMassFromShapes();//從圖形創建質量
//添加一些對象
for (var i:int = 1; i < 10; i++) {
bodyDef = new b2BodyDef();//剛體定義
bodyDef.position.x = Math.random() * 15 + 5;//位置:X
bodyDef.position.y = Math.random() * 10;//位置:Y
//取隨機框線參數
var rX:Number = Math.random() + 0.5;
var rY:Number = Math.random() + 0.5;
//盒(方塊)
if (Math.random() < 0.5) {//取隨機數
boxDef = new b2PolygonDef();//多邊形
boxDef.SetAsBox(rX, rY);//設定框線
boxDef.density = 1.0;//密度
boxDef.friction = 0.5;//摩擦力
boxDef.restitution = 0.2;//彈性
bodyDef.userData = new PhysBox();//用戶數據
bodyDef.userData.width = rX * 2 * 30; //寬
bodyDef.userData.height = rY * 2 * 30; //高
body = m_world.CreateBody(bodyDef);//創建剛體
body.CreateShape(boxDef);//創建BOX2D里的圖形
}
//圓
else {
circleDef = new b2CircleDef();//圓形
circleDef.radius = rX;//半徑
circleDef.density = 1.0;//密度
circleDef.friction = 0.5;//摩擦力
circleDef.restitution = 0.2//彈性
bodyDef.userData = new PhysCircle();//用戶數據
bodyDef.userData.width = rX * 2 * 30; //寬
bodyDef.userData.height = rX * 2 * 30; //高
body = m_world.CreateBody(bodyDef);//創建剛體
body.CreateShape(circleDef);//創建圖形
}
body.SetMassFromShapes();//從圖形創建質量
addChild(bodyDef.userData);//添加至舞台
}
//添加循環事件
addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
}
public function Update(e:Event):void{
m_world.Step(m_timeStep, m_iterations);//刷新物理世界
// 通過剛體列表更新Sprite的位置/角度
for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
//聲明bb = 世界對象的剛體列表; //bb(如果為空值, 即null, 0, underfind), 則不運行,
//bb = bb.m_next(下一個值為它的m_next)
if (bb.m_userData is Sprite){//如果數據是一個sprite
bb.m_userData.x = bb.GetPosition().x * 30;//設定X
bb.m_userData.y = bb.GetPosition().y * 30;//設定Y
bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI); //設定角度
}
}
}
}
}
說明:Box2D會自動管理各個物體的碰撞,彈跳等物理狀態,我們只需要創建各種剛體。創建剛體可以通過b2BodyDef.userData來創建。b2Shape.SetAsBox(width,height)指的是物體的半寬和半高,所以在計算時都要乘以2。由於Box2D本身的限制,運算時要進行長度換算。
1 創建一個世界(邊界,重力,休眠開關)
*********************************************************
//創建世界邊界
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set( -100.0, -100.0);//上限
worldAABB.upperBound.Set(100.0, 100.0);//下限
worldAABB 應該永遠比物體所在的區域要大,讓 worldAABB 更大總比太小要好.如果一個物體到達了 worldAABB 的邊界,它就會被凍結並停止模擬.
*********************************************************
//確定重力
var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
//允許引擎睡眠
var doSleep:Boolean = true;
接下來我們定義重力矢量.是的,你可以使重力朝向側面(或者你只好轉動你的顯示器).並且,我們告訴世界(world)當物體停止移動時允許物體休眠.一個休眠中的物體不需要任何模擬.
*********************************************************
//構建一個世界對象
m_world = new b2World(worldAABB, gravity, doSleep);//邊界,重力,睡眠開關
那么現在我們有了自己的物理世界,讓我們再加些東西進
*********************************************************
2 創建一個地面盒或者物體
*********************************************************
1.使用位置(position),阻尼(damping)等定義一個物體
2.使用世界對象創建物體
3.使用幾何結構,摩擦,密度等定義形狀
4.在物體上創建形狀
5.可選地調整物體的質量以和附加的形狀相匹配
*********************************************************
bodyDef = new b2BodyDef();//剛體定義
bodyDef.position.Set(10, 12);//位置
設定位置
*********************************************************
boxDef = new b2PolygonDef();//多邊形定義
boxDef.SetAsBox(30, 3);//設定框線
boxDef.friction = 0.3;//摩擦力
boxDef.density = 0;//密度,靜態物體需要0密度
設定虛擬屬性,密度為0即是靜態物體(障礙物)
*********************************************************
bodyDef.userData = new PhysGround();//用戶數據
bodyDef.userData.width = 30 * 2 * 30;//寬
bodyDef.userData.height = 30 * 2 * 3;//高
addChild(bodyDef.userData);//添加至舞台
創建顯示對象
*********************************************************
body = m_world.CreateBody(bodyDef);//創建物體
body.CreateShape(boxDef);//創建圖形
body.SetMassFromShapes();//從圖形創建質量
把顯示對象寫入世界坐標,再把虛擬屬性寫入顯示對象,最後從圖形創建質量
*********************************************************
&mtxNj8]

相關詞條

熱門詞條

聯絡我們