i had combine sfml and box2d. but i have an error in the source code. in this code sf::Shape* shape = static_cast<sf::Shape*>(body->GetUserData()); how to convert from b2bodyuserdata to sf::shape??
and this code delete static_cast<sf::RectangleShape*>(body->GetUserData()); how to convert from b2bodyuserdata to sf::rectangle??
i expect to run this program successfuly.
this the source code
converter.h
namespace converter
{
constexpr double PIXELS_PER_METERS = 32.0;
constexpr double PI = 3.14159265358979323846;
template<typename T>
constexpr T pixel_to_meters(const T& x)
{
return x/PIXELS_PER_METERS;
};
template<typename T>
constexpr T meters_to_pixels(const T& x)
{
return x*PIXELS_PER_METERS;
};
template<typename T>
constexpr T deg_to_rad(const T& x)
{
return PI*x/180.0;
};
template<typename T>
constexpr T rad_to_deg(const T& x)
{
return 180.0*x/PI;
}
}
main.cpp
#include "converter.hpp"
#include <Box2D/Box2D.h>
#include <SFML/Graphics.hpp>
#include <list>
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);
//deprected
//res->SetUserData(shape);
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());
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)//Close window
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());
world.DestroyBody(body);
}
return 0;
}
GetUserData()
returns a reference to a b2BodyUserData
, which is a struct with a single pointer
member.
So the two lines you mention should be:
sf::Shape* shape = reinterpret_cast<sf::Shape*>(body->GetUserData().pointer);
and
delete reinterpret_cast<sf::RectangleShape*>(body->GetUserData().pointer);