You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SFML与Box2D结合时b2BodyUserData转sf::Shape类型报错求助

解决Box2D与SFML结合时的b2BodyUserData类型转换错误

核心问题根源

你使用的Box2D新版本中,b2Body::GetUserData()返回的是**b2BodyUserData结构体**,而非旧版本的直接指针类型。你在存储数据时已经正确设置了结构体的pointer成员,但读取时错误地直接转换整个结构体,导致类型不匹配。

关键代码修改

1. 修正display_world函数中的指针读取

将原来的类型转换代码:

sf::Shape* shape = static_cast<sf::Shape*>(body->GetUserData());

改为:

sf::Shape* shape = static_cast<sf::Shape*>(body->GetUserData().pointer);

2. 修正main函数中的内存释放代码

将原来的delete语句:

delete static_cast<sf::RectangleShape*>(body->GetUserData());

改为:

delete static_cast<sf::RectangleShape*>(body->GetUserData().pointer);

3. 修复命名空间引用错误

你的代码中调用了book::create_box和book::display_world,但这两个函数并未放在book命名空间内,需要补充命名空间定义:

namespace book
{
    b2Body* create_box(b2World& world,int pos_x,int pos_y, int size_x,int size_y,b2BodyType type = b2_dynamicBody)
    {
        // 原函数逻辑保持不变
    }

    void display_world(b2World& world,sf::RenderWindow& render)
    {
        // 已修改指针读取逻辑的函数内容
    }
}

完整修改后的关键代码片段

namespace book
{
    b2Body* create_box(b2World& world,int pos_x,int pos_y, int size_x,int size_y,b2BodyType type = b2_dynamicBody)
    {
        b2BodyDef bodyDef;
        bodyDef.position.Set(converter::pixel_to_meters<double>(pos_x),converter::pixel_to_meters<double>(pos_y));
        bodyDef.type = type;

        b2PolygonShape b2shape;
        b2shape.SetAsBox(converter::pixel_to_meters<double>(size_x/2.0),converter::pixel_to_meters<double>(size_y/2.0));

        b2FixtureDef fixtureDef;
        fixtureDef.density = 1.0;
        fixtureDef.friction = 0.4;
        fixtureDef.restitution= 0.5;
        fixtureDef.shape = &b2shape;

        b2Body* res = world.CreateBody(&bodyDef);
        res->CreateFixture(&fixtureDef);

        sf::Shape* shape = new sf::RectangleShape(sf::Vector2f(size_x,size_y));
        shape->setOrigin(size_x/2.0,size_y/2.0);
        shape->setPosition(sf::Vector2f(pos_x,pos_y));

        if(type == b2_dynamicBody)
            shape->setFillColor(sf::Color::Blue);
        else
            shape->setFillColor(sf::Color::White);
        
        res->GetUserData().pointer = (uintptr_t)shape;

        return res;
    }

    void display_world(b2World& world,sf::RenderWindow& render)
    {
        world.Step(1.0/60,int32(8),int32(3));

        render.clear();

        for (b2Body* body=world.GetBodyList(); body!=nullptr; body=body->GetNext())
        {   
            sf::Shape* shape = static_cast<sf::Shape*>(body->GetUserData().pointer);
            shape->setPosition(converter::meters_to_pixels(body->GetPosition().x),converter::meters_to_pixels(body->GetPosition().y));
            shape->setRotation(converter::rad_to_deg<double>(body->GetAngle()));
            render.draw(*shape);
        }

        render.display();
    }
}

int main(int argc,char* argv[])
{
    sf::RenderWindow window(sf::VideoMode(800, 600, 32), "04_Basic");
    window.setFramerateLimit(60);

    b2Vec2 gravity(0.f, 9.8f);
    b2World world(gravity);

    std::list<b2Body*> bodies;

    bodies.emplace_back(book::create_box(world,400,590,800,20,b2_staticBody));

    while(window.isOpen())
    {
        sf::Event event;
        while(window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            int x = sf::Mouse::getPosition(window).x;
            int y = sf::Mouse::getPosition(window).y;
            bodies.emplace_back(book::create_box(world,x,y,32,32));
        }
        book::display_world(world,window);
    }

    for(b2Body* body : bodies)
    {
        delete static_cast<sf::RectangleShape*>(body->GetUserData().pointer);
        world.DestroyBody(body);
    }

    return 0;
}

说明

Box2D新版本废弃了直接的SetUserData(void*)接口,改用b2BodyUserData结构体存储自定义数据,其中pointer成员用于存放指针类型数据。你之前的存储逻辑是正确的,只需在读取时访问pointer成员即可完成正确的类型转换。

内容的提问来源于stack exchange,提问作者lie ardi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 14:51:24