(转载)BOX2D V2.3.0 用户手册中文版(第2章)-Hello Box2D
(轉載)BOX2D V2.3.0 用戶手冊中文版(第2章)-Hello Box2D
Chapter 2 Hello Box2D
Box2D的發布包中有個Hello World程序。程序創建了一個大大的地面盒(ground box)和一個小小的動態盒(dynamic box)。代碼沒有涉及到圖形界面,你只能在控制臺中看到隨時間變化的盒子位置的文字輸出。
這是個很好的例子, 展示了怎么學習和使用Box2D。
2.1 創建世界
每個Box2D程序開始時都會創建一個b2World對象。b2World是個物理樞紐(physics hub),用于管理內存、對象和模擬。你可以在棧, 堆或數據區中創建出world。
創建Box2D的world很簡單。首先,我們定義重力矢量。
現在可以創建world對象了。注意,我們是在棧中創建world, 所以world不能離開它的作用域。
b2World world(gravity);現在我們已經有了自己的物理世界,開始向里面加東西了。
2.2 創建地面盒
body用以下步驟來創建:
1. 用位置(position), 阻尼(damping)等來定義body。
2. 用world對象來創建body。
3. 用形狀(shape), 摩擦(friction), 密度(density)等來定義fixture。
4. 在body上來創建fixture。
第一步,創建ground body。
為此我們需要一個body定義。在定義中,我們指定ground body的初始位置。
b2BodyDef groundBodyDef; groundBodyDef.position.Set(0.0f, -10.0f);第二步,將body定義傳給world對象,用以創建ground body。
world對象并不保留body定義的引用。body默認是靜態的。靜態物體和其它靜態物體之間并沒有碰撞,它們是固定的。
b2Body* groundBody = world.CreateBody(&groundBodyDef);第三步,創建地面多邊形。
我們用簡便函數SetAsBox使得地面多邊形構成一個盒子形狀,盒子的中心點就是父body的原點。
b2PolygonShape groundBox; groundBox.SetAsBox(50.0f, 10.0f);SetAsBox函數接收半個寬度和半個高度作為參數。因此在這種情況下,地面盒就是100個單位寬(x軸),20個單位高(y軸)。Box2D已被調諧 到使用米,千克和秒做單位。你可以認為長度單位就是米。當物體的大小跟真實世界一樣時,Box2D通常工作良好。例如,一個桶約1米高。由于浮點算法的局 限性,使用Box2D模擬冰川或沙塵的運動并不是一個好主意。
第四步,我們創建shape fixture,以完成ground body。
在這步中,我們有個簡便方法。我們并不需要修改fixture默認的材質屬性,可以直接將形狀傳給body而不需要創建fixture的定義。隨后的教程中,我們將會看到如何使用fixture定義來定制材質屬性。第二個參數是形狀密度,單位是千克/平方米。靜態物體的質量定義為0,因此密度對它們是沒有用的。
groundBody->CreateFixture(&groundBox, 0.0f);Box2D并不保存shape的引用。它把數據復制到一個新的b2Shape對象中。
注意
每個fixture都必須有一個父body,即使fixture是靜態的。然而,你可以把所有的靜態fixture都依附在單個靜態body之上。
當你使用fixture 向body添加shape的時候,shape的坐標對于body來說就變成本地的了。因此當body移動的時候,shape也一起移動。fixture的世界變換繼承自它的父body。fixture沒有獨立于body的變換。所以我們不需要移動body上的shape。不支持移動或修改body上的shape。原因很簡單:形狀發生改變的物體不是剛體,而Box2D只是個剛體引擎。Box2D所做的很多假設都是基于剛體模型的。如果這一條被改變的話,很多事情都會出錯。
2.3 創建動態物體
現在我們已經有了一個地面body,我們可以使用同樣的方法來創建一個動態body。除尺寸之外的主要區別是,我們必須為動態body設置質量屬性。
首先我們用CreateBody創建body。默認情況下,body是靜態的,所以在構造時候應該設置b2BodyType,使得body成為動態的。
注意
如果你想讓body受力的影響而運動, 你必須將body的類型設為b2_dynamicBody。
然后,我們創建一個多邊形shape, 并將它附加到fixture定義上。我們先創建一個box shape:
b2PolygonShape dynamicBox; dynamicBox.SetAsBox(1.0f, 1.0f);接下來,我們使用box創建一個fixture定義。注意, 我們把密度值設置為1,而密度值默認是0。并且,shape的摩擦系數設置為0.3。
b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicBox; fixtureDef.density = 1.0f; fixtureDef.friction = 0.3f;注意
一個動態body至少有一個密度不為0的fixture。否則會出現一些奇怪的行為。
使用fixture定義,我們現在就可以創建fixture。這會自動更新body的質量。要是你喜歡,你可以為body添加許多不同的fixture。每個fixture都會增加物體的總質量。
body->CreateFixture(&fixtureDef);這就是初始化過程。現在我們已經做好準備,可以開始模擬了。
2.4 模擬(Box2D的)世界
我們已經初始化了地面box和一個動態box。該讓牛頓來接手了。我們只有少數幾個問題需要考慮。
Box2D使用了一種名叫積分器(integrator)的數值算法。 積分器在離散的時間點上模擬物理方程。 它與傳統的游戲動畫循環一同運行。我們需要為Box2D選取一個時間步(time step)。通常來說用于游戲的物理引擎需要至少 60Hz 的速度,也就是 1/60 秒的時間步。你可以使用更大的時間步,但是你必須更加小心地為你的世界調整定義。我們也不喜歡時間步變化得太大,一個變化的時間步會導致變化的結果,這會給調試帶來困難。所以不要把時間步關聯到幀頻(除非你真的必須這樣做)。直截了當地,這個就是時間步。
除積分器外,Box2D代碼還使用了約束求解器(constraint solver)。約束求解器用于解決模擬中的所有約束,一次一個。單個的約束會被完美的求解,然而當我們求解一個約束的時候,我們就會稍微干擾另一個約束。要得到良好的解,我們需要多次迭代所有約束。
約束求解有兩個階段:速度階段和位置階段。在速度階段,求解器會計算必要的沖量,使得物體正確運動。而在位置階段,求解器會調整物體的位置,減少物體之間的重疊和關節的脫節。每個階段都有自己的迭代計數。此外,如果誤差已足夠小的話,位置階段的迭代可能會提前退出。
Box2D建議的迭代次數,對于速度是8次,對于位置是3次。你可以按自己的喜好去調整這個數字,但要記得它是性能與精度之間的折中。更少的迭代會增加性能但降低精度,同樣地,更多的迭代會降低性能但能提高模擬的質量。對于這個簡單示例,我們不需要很多的迭代。這里是我們選擇的迭代次數。
注意
時間步和迭代數是完全無關的。一個迭代并不是一個子步。一次迭代就是在時間步之中的單次遍歷所有約束,你可以在單個時間步內多次遍歷約束。
現在我們可以開始模擬循環了,在你的游戲中,模擬循環和游戲循環可以合并起來。每次游戲循環你都應該調用b2World::Step,通常調用一次就夠了,這取決于幀頻以及物理時間步。
這個Hello World程序設計得非常簡單,它沒有圖形輸出。代碼會打印出動態body的位置以及旋轉角。這就是模擬 1 秒鐘內 60 個時間步的循環。
輸出展示了box下降并降落到地面的情況。你的輸出看起來應當是這樣的:
0.00 4.00 0.00
0.00 3.99 0.00
0.00 3.98 0.00
…
0.00 1.25 0.00
0.00 1.13 0.00
0.00 1.01 0.00
2.5 清理
當world對象超出它的作用域,或通過指針將其 delete 時,分配給body、 fixture和 joint使用的內存都會被釋放。這能提升性能,并使你的生活變得更簡單。然而,你應該將body、fixture或joint的指針都清零,因為它們已經無效了。
2.6 The Testbed
一旦你征服了 HelloWorld 例子,你應該開始看 Box2D 的 testbed 了。testbed 是個單元測試框架,也是個演示環境,這是它的一些特點:
? 可移動和縮放的攝像機。
? 可用鼠標選中依附在動態物體上的形狀。
? 可擴展的測試集。
? 通過圖形界面選擇測試,調整參數,以及設置調試繪圖。
? 暫停和單步模擬。
? 文字渲染。
在 testbed 中有許多 Box2D 的測試用例,以及框架本身的實例。我鼓勵你通過研究和修改它來學習 Box2D。
注意
testbed 是使用 freeglut 和 GLUI 寫成的,testbed 本身并不是 Box2D 庫的一部分。Box2D本身并不知道如何渲染。就像 HelloWorld 例子一樣,使用 Box2D 并不一定需要渲染。
總結
以上是生活随笔為你收集整理的(转载)BOX2D V2.3.0 用户手册中文版(第2章)-Hello Box2D的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ps 究竟是 aux 还是 ef
- 下一篇: 企业邮箱价格多少钱?邮箱购买价格多少钱?