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 … 覚えないと… ^^;;