0

I'm writing a game for Mac OS using cocos2D and Box2D. I've added a b2ContactListener subclass to my world as follows:

contactListener = new ContactListener();
world->SetContactListener(contactListener);

This works perfectly, but I am unsure of the best/accepted way to access the contact listener from other classes that don't currently have a direct reference to the contact listener.

I know I can pass a reference to other classes that need it, but what I was wondering is if there is a better way. More specifically, although I can't find a method to do this, is there some equivalent of this:

world->GetContactListener();

in Box2D?

The reason I am trying to do this is simply because I would prefer to move some game logic (i.e. whether a body is able to jump based on information from the contact listener) to the relevant classes themselves, rather than putting everything in the main gameplay class.

Thanks!

4

2 回答 2

3

联系侦听器仅作为 BeginContact、EndContact、PreSolve 和 PostSolve 四个函数的入口点。通常它没有成员变量,所以没有理由得到它,因为没有任何东西可以从中得到。

当在世界步骤期间调用其中一个函数时,您可以记下哪两件事触摸/停止触摸等,但您不应该立即更改世界中的任何内容,直到时间步骤完成。

我认为这个问题的症结在于用于“记录”哪些事情被触及的方法,但这真的取决于你,取决于你需要什么样的信息。例如,如果您只对 BeginContact 感兴趣,那么绝对最简单的方法可能是将接触到的两个固定装置存储为对列表:

std::vector< std::pair<b2Fixture*, b2Fixture*> > thingsThatTouched;

//in BeginContact
thingsThatTouched.push_back( make_pair(contact->GetFixtureA(), contact->GetFixtureB()) );

//after the time step
for (int i = 0; i < thingsThatTouched.size(); i++) {
    b2Fixture* fixtureA = thingsThatTouched[i].first;
    b2Fixture* fixtureB = thingsThatTouched[i].second;
    // ... do something clever ...
}
thingsThatTouched.clear(); //important!!

为此,您需要使 thingsThatTouched 列表在联系侦听器函数中可见,因此它可以是全局变量,也可以在联系侦听器类中设置指向它的指针,或者可能有一个全局函数返回一个指向列表的指针。

如果您需要跟踪更多信息,例如停止触摸的事物,或者在时间步之后根据事物触摸时的影响程度等做某事,则需要更多的工作并且变得更加具体。您可能会发现这些教程很有用:

这个使用 BeginContact/EndContact 更新身体正在触摸的其他东西的列表,并使用它来决定玩家是否可以在任何给定时间跳跃: http ://www.iforce2d.net/b2dtut/jumpability

这个使用类似的方法来查看当前汽车轮胎下方的表面类型,以确定表面的摩擦力: http ://www.iforce2d.net/b2dtut/top-down-car

这个使用 PreSolve 根据撞击的速度来决定两个物体(箭头和目标)在碰撞时是否应该粘在一起。实际的“粘在一起”处理是在时间步完成后完成的: http ://www.iforce2d.net/b2dtut/sticky-projectiles

于 2012-06-05T16:47:28.123 回答
0

GetContactList如果您需要在其他地方进行操作,我认为您只需调用并使用迭代器处理所有联系人

于 2012-06-03T09:35:04.837 回答