Box2D-在运行时创建实体时,实体不会发生碰撞
Box2D - When creating a body at runtime, the body does not collide
我一直在开发一款具有可破坏环境的游戏,我提出了一个解决方案,可以在我的ContactListener
对象中检查可能的破坏。显然,因为这是在Step()
中发生的,所以我将销毁处理推迟到步骤之后。我通过汇集需要在联系人侦听器中处理的"销毁事件"来实现这一点,然后在Step()
之后立即调用类似contactListener->processDestructionEvents();
的东西。
我这样做的方法是在beginContact事件中捕捉碰撞的固定装置,然后确定碰撞角度,然后使用该角度对固定装置本身进行光线投射。然后,我从夹具的b2PolygonShape
抓取顶点,然后生成两个新的形状,根据光线的入射点和出射点进行分割。实体上的原始夹具将被销毁,然后为第一个新形状生成一个新夹具,并将其添加到原始实体中。对于第二个形状,将生成一个新实体,并将该形状添加到此新实体中。
不管怎样,一切都很好,在调试视图中,我可以看到新的形状已经生成,并且都在适当的位置。然而,在这一点上,我的行为真的很糟糕。一旦这个过程完成,原始物体和新生成的物体都不会与任何物体碰撞。如果我启用连续物理,有时动态对象会与这些物体/固定装置的某个边缘碰撞,但并不总是如此。我想知道我在运行时重建身体/固定装置的方法中是否做错了什么。以下是生成新对象的代码,如有任何帮助,将不胜感激。
void PhysicsContactListener::processDestructionEvents() {
if(!hasDestructionEvents) {return;}
for(destructionEventsIterator = destructionEvents.begin(); destructionEventsIterator != destructionEvents.end(); ++destructionEventsIterator) {
b2Filter f1, f2;
f1.groupIndex = destructionEventsIterator->originalFixture->GetFilterData().groupIndex;
f1.categoryBits = destructionEventsIterator->originalFixture->GetFilterData().categoryBits;
f1.maskBits = destructionEventsIterator->originalFixture->GetFilterData().maskBits;
f2.groupIndex = destructionEventsIterator->originalFixture->GetFilterData().groupIndex;
f2.categoryBits = destructionEventsIterator->originalFixture->GetFilterData().categoryBits;
f2.maskBits = destructionEventsIterator->originalFixture->GetFilterData().maskBits;
b2PolygonShape newShape0 = destructionEventsIterator->newFixtures[0];
b2FixtureDef fixture0Def;
fixture0Def.shape = &newShape0;
fixture0Def.density = 1.0f;
fixture0Def.restitution = 0.2f;
b2Fixture* fixture1 = destructionEventsIterator->hostBody->CreateFixture(&fixture0Def);
fixture1->SetFilterData(f1);
//destructionEventsIterator->hostBody->SetAwake(true);
destructionEventsIterator->hostBody->ResetMassData();
//destructionEventsIterator->hostBody->SetActive(true);
destructionEventsIterator->hostBody->SetTransform(destructionEventsIterator->hostBody->GetPosition(), destructionEventsIterator->hostBody->GetAngle());
b2BodyDef bd;
bd.position = destructionEventsIterator->hostBody->GetPosition();
bd.angle = destructionEventsIterator->hostBody->GetAngle();
bd.type = destructionEventsIterator->hostBody->GetType();
b2Body* newBody = destructionEventsIterator->hostBody->GetWorld()->CreateBody(&bd);
b2PolygonShape* newShape1 = (b2PolygonShape*)(&destructionEventsIterator->newFixtures[1]);
b2Fixture* fixture2 = newBody->CreateFixture(newShape1, destructionEventsIterator->hostBodyDensity);
fixture2->SetFilterData(f2);
newBody->SetAngularVelocity(destructionEventsIterator->hostBody->GetAngularVelocity());
newBody->SetLinearVelocity(destructionEventsIterator->hostBody->GetLinearVelocity());
//newBody->SetAwake(true);
newBody->ResetMassData();
//newBody->SetActive(true);
newBody->SetTransform(destructionEventsIterator->hostBody->GetPosition(), destructionEventsIterator->hostBody->GetAngle());
destructionEventsIterator->hostBody->DestroyFixture(destructionEventsIterator->originalFixture);
}
这两块不碰撞吗?看看每个夹具最终得到的categoryBits和maskBits值——看起来每个工件都有相同的值。我的猜测是,你只是忽略了这样一个事实,即这些掩码是通过两种方式相互检查的,例如来自Box2D源代码:
bool collide =
(filterA.maskBits & filterB.categoryBits) != 0 &&
(filterA.categoryBits & filterB.maskBits) != 0;
另一方面,如果你的意思是,这些碎片什么都没有碰撞,只是从地上掉下来,除了偶尔,永远掉下去,那么我可能会怀疑多边形缠绕不正确。
顺便说一句,b2Filter只包含基元,所以你可以直接分配它们:
b2Filter f1 = destructionEventsIterator->originalFixture->GetFilterData();
此外,第一个SetTransform和第二个ResetMassData是冗余的。
- 使用指针重新分析实体
- 落砂模拟碰撞检测C++和SFML
- 如何使用tinyxml2从XML加载父实体和子实体
- 不能将 "void *" 类型的值分配给类型 "TCHAR" 的实体
- SFML 碰撞永远不会在我的系统中注册
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 如何在 ECS 模型中组织实体?
- 在均匀网格中处理碰撞
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 有关纯 ECS(实体组件系统)和更新系统的问题
- 返回模板化实体的函数的概念
- 在 C++ 中编写解析器来解析给定的 HTML 实体
- 无法将错误分配给成员函数中"类型的实体"
- 如何访问基类向量中的子类变量?(对于实体组件系统)
- 平台游戏 - 下车时避免与平台碰撞
- "const wchar_t *" 类型的值不能用于初始化类型 "const PWSTR" 的实体
- Visual Studio C++:不能使用类型为 "const wchar_t *" 的值来初始化类型为 "TCHAR *" 的实体
- 两个实体之间的子弹碰撞回调
- Box2D-在运行时创建实体时,实体不会发生碰撞
- 追逐玩家的实体之间的碰撞检测