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
相关产品推荐
相关产品推荐

