【问题标题】:Box2D ContactListener Not Detecting CollisionBox2D ContactListener 未检测到碰撞
【发布时间】:2018-02-19 04:07:00
【问题描述】:

我正在尝试使用 b2ContactListener 类检测静态体和运动体之间的碰撞,但我的代码未检测到两个固定装置之间的碰撞。我在我的运动体顶部放置了一个 EdgeShape,并将其作为一个夹具来检测与我的静态体夹具的碰撞。我正在使用 SFML 绘制到屏幕并检测键盘事件。

这是我的主要功能:

int main()
{
    Vector2f resolution;
    resolution.x = VideoMode::getDesktopMode().width;
    resolution.y = VideoMode::getDesktopMode().height;

    RenderWindow window(VideoMode(resolution.x, resolution.y),
        "Box2D Test", Style::Fullscreen);

    Vector2f staticRectSize(100.0f, 20.0f);
    Vector2f kinematicRectSize(40.0f, 20.0f);

    Event keyBoardEvent;

    b2Vec2 gravity(0.0f, 0.0f);

    b2World world(gravity);

    // Creating static body and fixture
    b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(100.0f, 150.0f);

    b2Body* groundBody = world.CreateBody(&groundBodyDef);

    b2PolygonShape groundBox;

    groundBox.SetAsBox(50.0f, 10.0f);

    groundBody->CreateFixture(&groundBox, 0.0f);

    // Creating kinematic body and fixture
    b2BodyDef bodyDef;
    bodyDef.type = b2_kinematicBody;
    bodyDef.position.Set(125.0f, 700.0f);
    b2Body* body = world.CreateBody(&bodyDef);

    b2PolygonShape kinematicBox;
    kinematicBox.SetAsBox(20.0f, 10.0f);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = &kinematicBox;

    fixtureDef.density = 1.0f;

    fixtureDef.friction = 0.3f;

    body->CreateFixture(&fixtureDef);

    // world.Step inputs
    float32 timeStep = 1.0f / 60.0f;
    int32 velocityIterations = 6;
    int32 positionIterations = 2;

    RectangleShape staticRect(staticRectSize);
    RectangleShape dynamicRect(kinematicRectSize);

    b2Vec2 staticPosition = groundBody->GetPosition();
    staticRect.setPosition(staticPosition.x, staticPosition.y);

    b2Vec2 dynamicPosition = body->GetPosition();

    // Creating EdgeShape
    b2EdgeShape top;
    top.Set(b2Vec2(dynamicPosition.x, dynamicPosition.y), b2Vec2(dynamicPosition.x + 40.0, dynamicPosition.y));
    fixtureDef.shape = ⊤
    fixtureDef.isSensor = true;
    body->CreateFixture(&fixtureDef)->SetUserData("top collision");

    // Creating an instance of myContactListener class
    myContactListener contactListener;
    world.SetContactListener(&contactListener);

    while (window.isOpen())
    {
        world.Step(timeStep, velocityIterations, positionIterations);

        dynamicPosition = body->GetPosition();

        dynamicRect.setPosition(dynamicPosition.x, dynamicPosition.y);

        while (window.pollEvent(keyBoardEvent))
        {
            if (keyBoardEvent.type == Event::KeyPressed)
            {
                if (keyBoardEvent.key.code == Keyboard::W)
                {
                    body->SetLinearVelocity(b2Vec2(0, -10));
                }
    ...

            window.clear();
            window.draw(staticRect);
            window.draw(dynamicRect);
            window.draw(line);
            window.display();

            if (Keyboard::isKeyPressed(Keyboard::Escape))
            {
                break;
            }
        }
        return 0;
    }

这是我的 MyContactListiner.cpp:

void myContactListener::BeginContact(b2Contact* contact)
{
    b2Fixture *fa = contact->GetFixtureA();
    b2Fixture *fb = contact->GetFixtureB();

    if (fa == NULL || fb == NULL) { return; }

    while (1)
    {
        printf("Collision occurred");

        if (Keyboard::isKeyPressed(Keyboard::Escape))
        {
            break;
        }
    }
}

【问题讨论】:

    标签: c++ box2d sfml


    【解决方案1】:

    Box2D 不会对静态物体直接与其他静态或运动物体进行碰撞处理。它们在理论上都是无限质量的,运动定律似乎不再有意义(至少在碰撞方面对我来说不是)。

    将运动体改为动态体可能最容易。

    您也可以用动态的身体包围其中一个身体,以使接触侦听器启动。动态体不能驱动它所包围的运动学或静态体,但是在子步骤阶段,无需付出比我认为值得付出更多的努力。

    希望这个答案有帮助!

    【讨论】:

    • 感谢您的回复。正如您所建议的,将运动学体改为动态体基本上也是我想出的解决方案。将重力设置为 0 可以获得所需的效果。
    猜你喜欢
    • 1970-01-01
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多