在Box2D中获取世界的contactListener [英] Getting the world's contactListener in Box2D

查看:264
本文介绍了在Box2D中获取世界的contactListener的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用cocos2D和Box2D为Mac OS编写游戏.我在世界中添加了b2ContactListener子类,如下所示:

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();

在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.

谢谢!

推荐答案

联系侦听器仅用作BeginContact,EndContact,PreSolve和PostSolve四个功能的入口.通常,它没有成员变量,因此没有理由获得它,因为没有任何东西可以得到.

A contact listener just serves as an entry point for the four functions BeginContact, EndContact, PreSolve and PostSolve. Typically it has no member variables, so there is no reason to get it, because there is nothing to get from it.

在世界步中调用这些功能之一时,您可以记下已触摸/停止触摸的两件事等,但是在时间步完成之前,您不应立即更改世界中的任何内容.

When one of these functions is called during a world Step, you can make a note of which two things touched/stopped touching etc, but you should not change anything in the world right away, until the time step is complete.

我认为这个问题的症结在于用来记下"涉及哪些事物的方法,但这实际上取决于您,并且取决于您需要什么样的信息.例如,如果您只对BeginContact感兴趣,那么绝对最简单的方法可能就是将触摸过的两个灯具存储为对列表:

I think the crux of this question is the method used to 'make a note' of which things touched, but that's really up to you and depends on what kind of information you need. For example if you're only interested in BeginContact, then the absolute simplest way might be to just store which two fixtures touched as a list of pairs:

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列表可见,因此它可以是全局变量,也可以在接触侦听器类中设置指向它的指针,或者可能有一个返回指向列表的指针的全局函数.

For this to work you'll need to make the thingsThatTouched list visible from the contact listener function, so it could either be a global variable, or you could set a pointer to it in the contact listener class, or maybe have a global function that returns a pointer to the list.

如果您需要跟踪更多信息,例如停止触摸了哪些东西,或者根据触摸时的影响程度等在时间步长之后执行某些操作,则需要花费更多时间工作,变得更加具体.您可能会发现这些教程很有用:

If you need to keep track of more information such as what things stopped touching, or do something after the time step based on how hard things impacted when they touched etc, it will take a bit more work and becomes more specific. You might find these tutorials useful:

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

This one uses BeginContact/EndContact to update a list of which other things a body is touching, and uses it to decide if a player can jump at any given time: http://www.iforce2d.net/b2dtut/jumpability

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

This one uses a similar method to look at what type of surfaces are currently under a car tire, to decide how much friction the surface has: http://www.iforce2d.net/b2dtut/top-down-car

该对象使用PreSolve根据碰撞的速度来确定两个物体(箭头和目标)在碰撞时是否应该粘在一起.时间步骤完成后,将进行实际的粘在一起"处理: http://www.iforce2d.net/b2dtut/sticky-projectiles

This one uses PreSolve to decide whether two bodies (arrow and target) should stick together when they collide, based on the speed of the impact. The actual 'sticking together' processing is done after the time step finishes: http://www.iforce2d.net/b2dtut/sticky-projectiles

这篇关于在Box2D中获取世界的contactListener的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆