【Cocos2d-x】物理引擎使用入門,cocos2d-x物理引擎
相關概念
什麼是物理引擎?
科學模型:科學研究中對事物的合理簡化。
物理引擎是一個電腦程式類比牛頓力學模型,使用品質、速度、摩擦力和空氣阻力等變數。
可以用來預測這種不同情況下的效果。它主要用在科學類比和電子遊戲中。
一般,物理引擎只負責物理計算,而不進行畫面渲染。
關於box2d
Box2D是一款免費的開源二維物理引擎,由Erin Catto使用C++編寫。它已被用於蠟筆物理學、憤怒的小鳥、地獄邊境等遊戲的開發。
Cocos2d-x本身已經整合box2d。
以上解釋來自維基百科。
Box2D中文手冊:http://pan.baidu.com/s/1o63MI
Box2D源碼下載:https://code.google.com/p/box2d/downloads/list
Box2D首頁:http://box2d.org/
剛體(body)
在box2d中物體即剛體。
剛體就是堅硬的物體,碰撞不會產生形變。
物體的類型有以下3種:
靜態物體:碰撞不會移動。品質為0。如:邊界、牆。
動態物體:碰撞會移動。
平台物體:一直保持某一種運動的物體,如電梯會一直保持上下移動。
形狀(shape)
依附於剛體的2D碰撞幾何結構,形狀具有摩擦(friction)和恢複(restitution)的材料性質。
在Box2D中主要有以下兩種形狀:
1.圓形
2.多邊形
一個剛體的形狀,可以是由多個形狀組合而成。比如:人,頭是圓形,手、腳、身體都是矩形。
約束(constraint)
一個約束(constraint)就是消除物體自由度的物理串連。在 2D 中,一個物體有 3 個自由度。如果我們把一個物體釘在牆上(像擺錘那樣),那我們就把它約束到了牆上,而且此物體就只能繞著這個釘子旋轉,所以這個約束消除了它 2 個自由度。
接觸約束(contact constraint)
一個防止剛體穿透,以及用於類比摩擦(friction)和恢複(restitution)的特殊約束。你永遠都不必建立一個接觸約束,它們會自動被 Box2D 建立。
關節(joint)
它是一種用於把兩個或多個物體固定到一起的約束。Box2D 支援的關節類型有:旋轉,稜柱,距離等等。關節可以支援限制(limits)和馬達(motors)。
關節限制(joint limit)
一個關節限制(joint limit)限定了一個關節的運動範圍。例如人類的胳膊肘只能做某一範圍角度的運
動。
關節馬達(joint motor)
一個關節馬達能依照關節的自由度來驅動所串連的物體。例如,你可以使用一個馬達來驅動一個肘的
旋轉。
夾具(fixture)
剛體物理資訊(如:類型、密度係數、摩擦係數)的封裝。
一個剛體可以具有多個夾具。
摩擦
摩擦可以使對象逼真地沿其它對象滑動。Box2D 支援靜摩擦和動摩擦,但使用相同的參數。摩擦在Box2D 中會被正確地類比,並且摩擦力的強度與正交力(稱之為庫侖摩擦)成正比。摩擦參數經常會設定在 0 到 1 之間,0 意味著沒有摩擦,1 會產生強摩擦。
恢複
恢複可以使對象彈起,想象一下,在案頭上方丟下一個小球。恢複的值通常設定在 0 到 1 之間,0 的意思是小球不會彈起,這稱為非彈性碰撞;1 的意思是小球的速度會得到精確的反射,這稱為完全彈性碰撞。
密度
Box2D 可以根據附加形狀的品質分配來計算物體的品質以及轉動慣量。直接指定物體品質常常會導致不協調的類比。因此,推薦的方法是使用 b2Body::SetMassFromShape 來根據形狀設定品質。
世界(world)
世界就是一個封閉的多邊形。一般世界的大小和螢幕的大小一樣。處於世界中的物體才會進行計算,這是為了提高效率。
一個物理世界就是物體,形狀和約束相互作用的集合。
以上概述來自Box2D中文手冊。
在Cocos2d-x中使用Box2D
說明
開發環境說明:
引擎版本:Cocos2d-x2.2.1
開發工具:VS2012
系統:win7
工程配置
1.啟用Box2D:工程上右鍵——C/C++——前置處理器——前置處理器定義——編輯——添加宏(CC_ENABLE_BOX2D_INTEGRATION)
注意:Cocos2d-x中整合了Box2D和Chipmunk,但是這兩個物理引擎不能同時使用。啟用chipmunk的宏定義(CC_ENABLE_CHIPMUNK_INTEGRATION)
2.修改libExternsions項目的預先處理指令CC_ENABLE_CHIPMUNK_INTEGRATION為CC_ENABLE_BOX2D_INTEGRATION
3.連結box2d庫(libBox2d.lib)
Cocos2d-x2.2.6的一個bug
運行TestCpp中的Box2dTest時,當添加若干個方塊後會報如下錯誤。
縮放因子
Box2D中使用米、千克、秒作單位。但是一般作畫面渲染時都是以像素為單位的。
比如,我們在螢幕渲染一個寬為32像素的精靈,但是在物理空間中如何表示它的寬呢?
這時,就需要定義一個縮放因子用於將像素值轉換為物理空間的值。
把像素/米比率設定為32是一個比較合適的值,所以定義縮放因子的值為32.
// 定義縮放因子#define PTM_RATIO 32
建立物理世界
在CCLayer初始化的時候,初始化物理世界。
剛體與CCSprite綁定
Cocos2d-x中已經封裝了一個用於物理引擎的CCSprite,就是CCPhysicsSprite,這個類就定義在擴充庫中。#include "cocos-ext.h"就可以使用了。通過setB2Body方法與剛體進行關聯。
調試繪圖
b2Draw定義了用於繪製相關物理資訊的介面,只需要實現這些介面。並調用世界(world)的SetDebugDraw方法關聯DebugDraw。
DebugDraw在Cocos2d-x中已經有相關實現,就在cocos2d-x-2.2.1\samples\Cpp\TestCpp\Classes\Box2DTestBed目錄下的GLES-Render.cpp和GLES-Render.h。
1.把GLES-Render.cpp和GLES-Render.h拷貝到工程Classes目錄下。
2.包含標頭檔。
#ifdef _DEBUG#include "GLES-Render.h"#endif
3.在建立世界的時候,建立DebugDraw,設定Debug標記並關聯到世界。並重寫CCLayer的draw方法,繪製調試資訊。
4.在解構函式中釋放debugDraw佔用的記憶體。
Box2DTest::~Box2DTest(){CC_SAFE_DELETE(pWorld);CC_SAFE_DELETE(m_debugDraw);}
1.當物體受力的時候(碰撞、擠壓或下落),碰撞盒子的顏色會變成粉紅色,預設為青色。
2.最外邊的是剛體的形狀。
注意:建議先把縮放因子的值設定為64,然後再調試,這樣便於觀察,因為縮放因子為32時,碰撞盒子的大小和精靈的大小一樣。
樣本工程地址:https://coding.net/u/linchaolong/p/Cocos2d-x_HelloBox2D/git 【點擊下載源碼】