物理引擎box2d的學習心得

1 前言

     最近學習libgdx的時候暫時先沒看box2d那部分,昨天想作個物理效果看了一下那部分的封裝,發現沒點概念太難看懂了,仍是乖乖的把box2d先系統的學習一遍。這個資料網上不少,最好的天然是官方的用戶手冊,還有熱心網友把翻譯成中文的了。仍是老習慣,學完之後留點東西以備忘。html

2 基礎知識

    如下內容對理解物理引擎很是重要,摘自用戶手冊,這部分主要是給本身作備忘,強烈建議讀者把《box2d中文手冊》研讀一遍。java

2.1 必要知識

質量(mass),力(force),扭矩(torque)和衝量(impulses),這個不懂看看物理知識。c++

2.2 核心概念

形狀(shape)

2D幾何對象, 好比圓形(circle)或多邊形(polygon)。算法

剛體(rigid body)

十分堅硬的物質, 堅硬得像鑽石,它上面任意兩點之間的距離都保持不變。在後面的討論中,咱們用物體(body)來代替剛體。(這就使得物體自己不會產生形變,那軟軟彈彈的效果應該都是動畫)ide

夾具(fixture)

fixture將形狀綁定到物體之上, 並有必定的材質屬性, 好比密度(density), 摩擦(friction)和恢復(restitution)。性能

(譯註:一個物體和另外一物體碰撞, 碰撞後速度和碰撞前速度的比值會保持不變,這比值就叫恢復係數。)學習

約束(constraint)

約束是個物理鏈接, 用於消除物體的自由度。在2D中, 物體有3個自由度(水平,垂直,旋轉)。若是咱們把一個物體釘在牆上(像鐘擺那樣), 那就把它約束到了牆上。這個時候,此物體就只能繞着釘子旋轉, 因此這個約束消除了它2個自由度。動畫

(譯註:簡單的說, 須要用幾個參數來肯定物體的空間狀態, 這個物體就有幾個自由度。在二維中,徹底沒有約束的條件下, 咱們要肯定物體的狀態, 要有x座標, y座標, 旋轉角這三個參數, 因此自由度爲3。若是物體被釘在牆上, 只要有旋轉角,就能夠徹底肯定物體的狀態,有了釘子這個約束,物體自由度就變成了1。)spa

接觸約束(contact constraint)

一種特殊的約束, 設計的目的是爲了防止剛體被穿透, 也用於模擬摩擦和恢復。接觸約束不用你來建立, 它們會自動被Box2D生成。.net

關節(joint)

關節就是種約束, 用於將兩個或多個body固定到一塊兒。Box2D支持不一樣的關節類型:轉動(revolute),棱柱(prismatic),距離(distance)等。一些關節能夠有限制(limits)和馬達(motors)。

關節限制(joint limit)

關節限制限定了一個關節的運動範圍。例如人類的胳膊肘只能在某一角度範圍內運動。

關節馬達(joint motor)

根據關節的自由度, 關節馬達能夠驅動關節所鏈接的物體。例如, 你可使用一個馬達來驅動一個肘的旋轉。

世界(world)

一個物理世界就是各類, 剛體(bodies), 夾具(fixtures), 約束(constraints)相互做用的集合。 Box2D支持建立多個世界, 但這一般沒有必要。

box2d的內存是本身管理的,他創建了一個內存池,以減小對內存的頻繁的申請和釋放。因此全部對象都要box2d幫你建立,也就是libgdx中的world。

2.3 模擬物理世界的相關算法

積分器(integrator)的數值算法:在離散的時間點上模擬連續的物理方程它與傳統的遊戲動畫循環一同運行。咱們須要爲Box2D選取一個時間步。一般來講用於遊戲的物理引擎須要至少 60Hz 的速度,也就是 1/60 的時間步。你可使用更大的時間步,可是你必須更加當心地爲你的世界調整定義。咱們也不喜歡時間步變化得太大,因此不要把時間步關聯到幀頻(除非你真的必須這樣作)。直截了當地,這個就是時間步:

約束求解器(constraint solver):用於解決模擬中的全部約束,一次一個。單個的約束會被完美的求解,然而當咱們求解一個約束的時候,咱們就會稍微耽誤另外一個。要獲得良好的解,咱們須要屢次迭代全部約束。因此就有必要控制迭代計算的次數以防止無限循環,推薦迭代次數爲10能較好的模擬效果。

2.4 fixture中一些有意思的概念

密度(Density)

fixture的密度用來計算父物體的質量屬性。密度值能夠爲零或者是整數。你全部的fixture都應該使用類似的密度,這樣作能夠改善物體的穩定性。

當你添加一個fixture時,物體的質量會自動調整。

摩擦(Friction)

摩擦可使對象逼真地沿其它對象滑動。Box2D支持靜摩擦和動摩擦,二者都使用相同的參數。摩擦在Box2D中會被精確地模擬,摩擦力的強度與正交力(稱之爲庫侖摩擦)成正比。摩擦參數常常會設置在0到1之間, 也可以是其它的非負數,0意味着沒有摩擦, 1會產生強摩擦。當計算兩個形狀之間的摩擦時,Box2D必須聯合兩個形狀的摩擦參數。

恢復(Restitution)

恢復可使對象彈起。恢復的值一般設置在0到1之間。想象一個小球掉落到桌子上,值爲0表示着小球不會彈起, 這稱爲非彈性碰撞。值爲1表示小球的速度跟原來同樣,只是方向相反, 這稱爲徹底彈性碰撞

傳感器(Sensors)

有時候遊戲邏輯須要判斷兩個fixture是否相交,但卻不該該有碰撞反應。這能夠經過傳感器(sensor)來完成。傳感器也是個fixture,但只會偵測碰撞而不產生其它反應。

2.5 body中一些有意思的概念 

阻尼(Damping)

阻尼用於減少物體在世界中的速度。阻尼跟摩擦有所不一樣,摩擦僅在物體有接觸的時候纔會發生。阻尼並不能取代摩擦,每每這兩個效果須要同時使用。 

休眠參數(Sleep Parameters)

休眠是什麼意思? 模擬物體的成本是高昂的,因此若是物體更少,那模擬的效果就能更好。當物體中止了運動時, 咱們會但願中止模擬它 

固定旋轉(Fixed Rotation)

你可能想一個剛體,好比某個角色,具備固定的旋轉角。這樣物體即便在負載下,也不會旋轉。

×××(Bullets)

遊戲模擬一般以必定幀率(frame rate)產生一系列的圖片。這就是所謂的離散模擬。在離散模擬中,在一個時間步內剛體可能移動較大距離。默認狀況下,Box2D會經過連續碰撞檢測(CCD)來防止動態物體穿越靜態物體。通常狀況下,dynamic物體之間不會應用CCD,這是爲了保持性能。

3 libgdx中的box2d

3.1 libgdx的優點

    有個不得不說的優勢,box2d用戶手冊裏面有至關篇幅在說如何管理內存和引用,這個對於java程序而言真的是再不用多考慮了。

    另外,jbox2d版本在性能方面有些問題,但牛逼的是libgdx是經過jni調用的box2d的c++版本。

3.2 如何將actor和body聯繫起來

    這個問題真的有點讓我困擾,咱們指望的效果天然是actor能帶上物理特性,但遺憾的是不能直接這麼指定。這就形成了一個是在物理世界移動的物理,一個是動畫世界的圖片,二者卻沒有了直接關係。因此這就須要將這兩個東西聯繫在一塊兒,而後同步二者的爲止。

    目前以爲比較好的方式就是在上層再作一次封裝,將actor和相應的body綁定在一塊兒,每幀都先讓body去計算位移,而後再調整actor的位置。

4 總結

    物理引擎真的很強大,能經過對物理定義就變成一個能夠按物理邏輯運行的效果,但在這以前對於box2d的概念必須有所瞭解。在libgdx中調用box2d仍是比較方便的,就是惋惜還要本身去綁定。Loving libgdx ~~

 

參考資料:
1. box2d v2.0.1中文手冊:
http://wenku.baidu.com/view/153e4421af45b307e8719753.html
2. box2d與精靈(sprite)的同步:http://blog.u250.info/?p=121002
3. 使用box2d的注意事項:http://kongweile.iteye.com/blog/978718
4. box2d v2.1.0中文手冊(有譯註,也新一些,推薦):http://blog.csdn.net/complex_ok/article/details/6706982

相關文章
相關標籤/搜索