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

查看:22
本文介绍了在 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天全站免登陆