Box2D and Collisions
物体が衝突したときにイベントリスナー的なメソッドを呼び出させる仕組みがあるみたい。
今日はそこを試してみようと思います。
std::vector と b2ContactListenerを継承したクラス の扱い方…
やべーこういう実装…経験した事がないww ^^; …とりあえず写経www ^^;;;
まずは b2ContactListener を継承するクラスを追加(MyContactListener) と、std::vector に格納するための 構造体 MyContact を準備します。
//MyContactListener.h #include "cocos2d.h" #include "Box2d.h" #include <vector> #include <algorithm> #pragma mark - struct MyContact { b2Fixture * fixtureA; b2Fixture * fixtureB; bool operator == (const MyContact & other) const { bool result = (fixtureA == other.fixtureA) && (fixtureB == other.fixtureB); return result; } }; #pragma mark - class MyContactListener : public b2ContactListener { public: MyContactListener(); virtual ~MyContactListener(); public: std::vector<MyContact>_contacts; #pragma mark - ### b2ContactListener オーバーライド ### public: 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); };
#include "MyContactListener.h" #pragma mark - MyContactListener::MyContactListener() : _contacts() { } MyContactListener::~MyContactListener() { } #pragma mark - void MyContactListener::BeginContact(b2Contact *contact) { MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() }; _contacts.push_back(myContact); } void MyContactListener::EndContact(b2Contact *contact) { MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() }; std::vector<MyContact>::iterator pos; pos = std::find(_contacts.begin(), _contacts.end(), myContact); if (pos != _contacts.end()) { _contacts.erase(pos); } } void MyContactListener::PreSolve(b2Contact *contact, const b2Manifold *oldManifold) { } void MyContactListener::PostSolve(b2Contact *contact, const b2ContactImpulse *impulse) { }
…うーんw とりあえず雰囲気をつかむかww ^^;;;
下準備ができたので、 HelloWorld で、まず変数定義してクラス変数を準備ですね。
//HelloWorldScene.h #include "MyContactListener.h" class HelloWorld : public cocos2d::CCLayer { //...(省略) protected: MyContactListener * _contactListener; //...(省略) };
aaa
//HelloWorldScene.cpp HelloWorld::HelloWorld() { //...(省略) _contactListener = NULL; } HelloWorld::~HelloWorld() { //...(省略) CC_SAFE_DELETE(_contactListener); _contactListener = NULL; } bool HelloWorld::init() { bool result = false; do { const CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); //const CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); const CCPoint center = ccpMult(ccpFromSize(visibleSize), 0.5f); this->initPhysics(); //Create Contact Listener { _contactListener = new MyContactListener(); //今回のポイント _world->SetContactListener(_contactListener); } //...(省略) result = true; } whild(0); return result; }
これで準備はOKみたい。床とボールの衝突判定の実装は updateに記述。
あーなるほど…ココで b2Fixture を使うのかー… ^^;
{ std::vector<MyContact>::iterator pos; for (pos = _contactListener->_contacts.begin(); pos != _contactListener->_contacts.end(); pos++) { MyContact contact = *pos; if (((contact.fixtureA == _bottomFixture) && (contact.fixtureB == _ballFixture )) || ((contact.fixtureA == _ballFixture ) && (contact.fixtureB == _bottomFixture))) { CCLOG("%s Ball hit Bottom!!", __PRETTY_FUNCTION__); } } }
シミュレーターで試してみると、XCodeのアウトプットにログが出力されるwww
std::vector … 覚えないと… ^^;;