Box2d - 在运行时更改接触过滤器

3
我正在使用cocos2d (iOS)和box2d创建游戏。 我已经到了需要在模拟过程中更改接触过滤器的地步,想知道如何进行此操作。 我需要使用掩码位和类别位,这很好,我只是不确定如何将它们应用于b2body mid game。
我在思考是否需要在初始化时检索b2body的原始b2fixture或b2fixturedef,然后相应地修改值,然后调用刷新方法-world.Refilter()?
这听起来准确吗?
非常感谢您的任何建议。 Oliver.
3个回答

9
b2Filter filter;

for ( b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext() ) {
    f->GetFilterData( &filter );
    filter.categoryBits = ...;
    filter.maskBits = ...;
    filter.groupIndex = ...;
    f->SetFilterData( &filter );
}

显然,这将更改身体上所有灯具的过滤器设置 - 如果您想更加有选择性,您需要能够以某种方式区分哪个灯具是哪个。例如,如果您知道它是唯一的圆形灯具,您可以查看灯具类型来决定,否则您将不得不利用灯具的用户数据。


0

您可以在b2World中迭代所有物体。对于每个物体,您可以迭代其fixture并更改其filter。要识别您的物体,您可以使用userData。


我的所有b2Body都是从我的基类合成的,因此我可以这样做:b2Fixture *fix = object.body->GetFixture()? - Ospho
@Oliver: 如果你有指向b2body的指针,你可以获取装置列表。 - Andrew

0
iforce2d的答案可能已经过时了。我使用box2d v2.2.1,cocos2D v2.0.0和Xcode v4.5.2成功地运行了以下代码(在这里,我假设我有一个指向名为“body”的b2Body的指针,它只有一个fixture,即我不会迭代身体上的所有fixture):
b2Fixture *fix = body->GetFixtureList();
b2Filter filter = fix->GetFilterData();   
filter.groupIndex = -1*kPlayerGroupIndex; 
fix->SetFilterData(filter);

在上面的代码中,我防止了“body”与我的玩家身体发生碰撞,它们都具有相同的groupIndex值,即-1*kPlayerGroupIndex,其中kPlayerGroupIndex是一个正整数常量。任何具有这种负groupIndex的物体都不会相互碰撞。您还可以相应地更新categoryBits或maskBits以防止碰撞发生。
在我引用的版本号中,GetFilterData(&filter)和SetFilterData(&filter)对我返回错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接