實例介紹Cocos2d-x中Box2D物理引擎:碰撞檢測
virtual void BeginContact(b2Contact* contact)。兩個物體開始接觸時會響應,但僅僅調用一次。
virtual void EndContact(b2Contact* contact)。分離時響應。
但僅僅調用一次。
virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)。持續接觸時響應,它會被多次調用。
virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)。持續接觸時響應,調用完preSolve後調用。
以下通過將12.2.3一節的實例採用Box2D技術重構。了解一下Box2d物理引擎中怎樣檢測碰撞。
首先我們須要在project中加入一個新類。
使用Visual Studio 2012中加入一個新類。須要分別加入C++源文件和頭文件。詳細操作,如圖所看到的。右鍵點擊projectHelloBox2D下的Classes目錄。在右鍵菜單中選擇。“加入”→ “新項目”。
彈出如後面的圖所看到的加入新項對話框,我們在對話框中選擇文件的種類,在“名稱”中輸入文件名稱ContactListener,然後點擊“加入”button加入文件。
Visual Studio 2012中加入新類
加入新項對話框加入完畢新類ContactListener。我們還須要改動它的代碼,ContactListener.h文件代碼例如以下:
#include "cocos2d.h" #include "Box2D/Box2D.h" USING_NS_CC; class ContactListener : public b2ContactListener { private: //兩個物體開始接觸時會響應 virtual void BeginContact(b2Contact* contact); //持續接觸時響應 virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold); //持續接觸時響應,調用完preSolve後調用 virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse); //分離時響應 virtual void EndContact(b2Contact* contact); }; 在頭文件裏須要引入cocos2d.h和Box2D/Box2D.h頭文件,否則會有編譯錯誤。ContactListener採用共同擁有繼承b2ContactListener。 ContactListener.cpp文件代碼例如以下: #include "ContactListener.h" void ContactListener::BeginContact(b2Contact* contact) ① { log("BeginContact"); b2Body* bodyA = contact->GetFixtureA()->GetBody(); ② b2Body* bodyB = contact->GetFixtureB()->GetBody(); ③ auto spriteA = (Sprite*)bodyA->GetUserData(); ④ auto spriteB = (Sprite*)bodyB->GetUserData(); ⑤ if (spriteA != nullptr && spriteB != nullptr) ⑥ { spriteA->setColor(Color3B::YELLOW); spriteB->setColor(Color3B::YELLOW); } } void ContactListener::EndContact(b2Contact* contact) ⑦ { log("EndContact"); b2Body* bodyA = contact->GetFixtureA()->GetBody(); b2Body* bodyB = contact->GetFixtureB()->GetBody(); auto spriteA = (Sprite*)bodyA->GetUserData(); auto spriteB = (Sprite*)bodyB->GetUserData(); if (spriteA != nullptr && spriteB != nullptr) { spriteA->setColor(Color3B::WHITE); spriteB->setColor(Color3B::WHITE); } } void ContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) ⑧ { log("PreSolve"); } void ContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) ⑨ { log("PostSolve"); }
上述代碼第①行是實現碰撞事件BeginContact函數,第②代碼和第③行代碼是獲得接觸兩方物體對象。第④代碼和第⑤行代碼是從物體對象的UserData屬性中確定精靈對象,UserData屬性可以放置不論什麽對象,這裏我們可以通過bodyA->GetUserData()語句取得精靈,那是由於在定義物體的時候通過body->SetUserData(sprite)語句,將精靈放入到物體的UserData屬性。
第⑥行代碼是推斷兩個精靈是否存在。
代碼第⑦行是實現碰撞事件EndContact函數。函數的實現與BeginContact函數相似。第⑧和第⑨行代碼是實現碰撞事件PreSolve和PostSolve函數。這兩個函數通經常使用的不多。
我們還須要在要監聽事件的層中,加入相關碰撞檢測代碼。在HelloWorld.h的代碼例如以下:
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "Box2D/Box2D.h" #include "ContactListener.h" ① #define PTM_RATIO 32 class HelloWorld : public cocos2d::Layer { b2World* world; ContactListener* contactListener; ② public: ~HelloWorld(); static cocos2d::Scene* createScene(); virtual bool init(); virtual void update(float dt); virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event); CREATE_FUNC(HelloWorld); void initPhysics(); void addNewSpriteAtPosition(cocos2d::Vec2 p); }; #endif // __HELLOWORLD_SCENE_H__
上述代碼第①行是引入頭文件ContactListener.h。第②行代碼是聲明ContactListener類型的成員變量contactListener。
我們還須要改動HelloWorld.cpp中的HelloWorld::initPhysics()代碼例如以下:
void HelloWorld::initPhysics() { … … contactListener = new ContactListener(); world->SetContactListener(contactListener); … … }
函數中的contactListener = new ContactListener()語句是創建ContactListener對象,採用了newkeyword分配內存,創建成員變量contactListener,須要自己釋放contactListener對象。這些釋放過程是在析構函數中進行。它的析構函數代碼例如以下:
HelloWorld::~HelloWorld()
{
CC_SAFE_DELETE(world);
CC_SAFE_DELETE(contactListener);
}
使用CC_SAFE_DELETE(contactListener)安全釋放contactListener成員變量的內存。
很多其它內容請關註最新Cocos圖書《Cocos2d-x實戰 C++卷》?本書交流討論站點:http://www.c
很多其它精彩視頻課程請關註智捷課堂Cocos課程:http://v.51w
歡迎增加Cocos2d-x技術討論群:257760386?
《Cocos2d-x實戰 C++卷》現已上線,各大商店均已開售:?
京東:http://item.jd.com/11584534.html
亞馬遜:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU
當當:http://product.dangdang.com/23606265.html
互動出版網:http://product.china-pub.com/3770734?
《Cocos2d-x實戰 C++卷》源代碼及樣章下載地址:
源代碼下載地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1
樣章下載地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1 ?
歡迎關註智捷iOS課堂微信公共平臺實例介紹Cocos2d-x中Box2D物理引擎:碰撞檢測