Box2d をやってみる… チュートリアル2 (9) b2ContactListener

Box2D and Collisions
物体が衝突したときにイベントリスナー的なメソッドを呼び出させる仕組みがあるみたい。
今日はそこを試してみようと思います。

std::vector と b2ContactListenerを継承したクラス の扱い方…
やべーこういう実装…経験した事がないww ^^; …とりあえず写経www ^^;;;

まずは b2ContactListener を継承するクラスを追加(MyContactListener) と、std::vector に格納するための 構造体 MyContact を準備します。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//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);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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 で、まず変数定義してクラス変数を準備ですね。

1
2
3
4
5
6
7
8
9
10
11
//HelloWorldScene.h
 
#include "MyContactListener.h"
 
class HelloWorld : public cocos2d::CCLayer
{
//...(省略)
protected:
    MyContactListener * _contactListener;
//...(省略)
};

aaa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//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 を使うのかー… ^^;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
    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 … 覚えないと… ^^;;


Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です