Box2D 形状从世界中掉落

发布于 2025-01-03 01:15:57 字数 1365 浏览 0 评论 0原文

我在使用 Box2D(在 iOS 下)时遇到了这个非常奇怪的问题。我有一个身体放在屏幕底部。如果我使用 body->SetType(b2_staticBody) 将主体从 b2_dynamicBody 设置为 b2_staticBody,然后将其设置回 b2_dynamicBody,它会快速从屏幕底部落下(几帧为我可以看到它向下移动),然后被推回到地板上并正确静止。

这种行为似乎只发生在屏幕底部。对坐在一起的其他身体做同样的事情不会产生这种行为。

我将屏幕边缘定义如下(screenRect已经根据世界空间进行了调整):

b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body* groundBody = globalWorld->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p1.y), b2Vec2(screenRect.p2.x,       screenRect.p1.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p1.y), b2Vec2(screenRect.p1.x, screenRect.p2.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p2.y), b2Vec2(screenRect.p2.x, screenRect.p2.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p2.x,screenRect.p2.y), b2Vec2(screenRect.p2.x,       screenRect.p1.y));
groundBody->CreateFixture(&boxShapeDef);

最奇怪的部分是我将身体从动态切换到静态的次数越多,它在被推回之前在地板上掉落的距离就越远。

除了从动态到静态之外,我没有改变身体的其他任何东西。如果我移动身体并将其放回地板上,开始将其从动态切换为静态,它会重置它掉落到地板上的程度,但我切换得越多,它就会再次增加。

我不明白为什么它会像这样从地板上掉下来,除非我错误地创建了它。游戏中的其他一切都完美运行。

I have this very odd problem with Box2D (under iOS). I have a body that is resting on the bottom of the screen. If I set the body from b2_dynamicBody to b2_staticBody using body->SetType(b2_staticBody), then later set it back to b2_dynamicBody, it falls through the bottom of the screen for a quick moment (several frames as I can see it moving down) before being pushed back up through the floor and coming to a rest correctly.

This behavior seems to only happen on the bottom of the screen. Doing the same thing with other bodies sitting on each other does not product this behavior.

I am defining the screen edges as follows (screenRect as already been adjust to world space):

b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body* groundBody = globalWorld->CreateBody(&groundBodyDef);
b2PolygonShape groundBox;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundBox;
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p1.y), b2Vec2(screenRect.p2.x,       screenRect.p1.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p1.y), b2Vec2(screenRect.p1.x, screenRect.p2.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p1.x,screenRect.p2.y), b2Vec2(screenRect.p2.x, screenRect.p2.y));
groundBody->CreateFixture(&boxShapeDef);
groundBox.SetAsEdge(b2Vec2(screenRect.p2.x,screenRect.p2.y), b2Vec2(screenRect.p2.x,       screenRect.p1.y));
groundBody->CreateFixture(&boxShapeDef);

The oddest part of this is the more I switch the body from dynamic to static, the farther and farther it falls through the floor before being pushed back up.

I have not changing anything else in the body except from dynamic to static. If I move the body and drop it back onto the floor, the start switching it from dynamic to static, it resets how much it's drop into the floor, but it build up again the more I switch.

I can't figure out why is is falling through the floor like this unless I'm creating it incorrectly. Everything else in the game works perfectly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寒江雪… 2025-01-10 01:15:57

我也有这个问题。这是我的理论:当物体处于静态时,它会停止与地面等其他静态物体产生接触。因此,似乎当再次设置为动态时,它无法更新此联系人检查。

我的解决方案是这样的:由于更改对象的位置会正确更新这些联系人,因此我只需将对象移动到其当前位置即可。不幸的是,它被检测为零变化。因此,我需要将其移至其他位置,然后再次将其移至之前的位置。

b2Vec2 pos = body.getPosition();
float ang = body.getAngle();
b2Vec2 off_map(-100,-100);
body.setPositionAndAngle(off_map, 0);
body.setPositionAndAngle(pos, ang);

如果您没有地图外区域,您可以尝试在第一次移动时停用该对象。

I had this problem too. Here is my theory: when the object is static, it stops generating contacts with other static stuff like the ground. So, it seems that when set to dynamic again, it fails to update this contact checking.

My solution was this: since changing the position of an object correctly update these contacts, I just move the object to its current place. Unfortunately, it's detected as a zero change. So, I need to move it elsewhere, then move it again to its previous position.

b2Vec2 pos = body.getPosition();
float ang = body.getAngle();
b2Vec2 off_map(-100,-100);
body.setPositionAndAngle(off_map, 0);
body.setPositionAndAngle(pos, ang);

If you don't have an off-map area, you can try deactivating the object during the first move.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文