Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Intergracja Box2D i SFML 2.1

Ostatnio zmodyfikowano 2013-11-04 18:07
Autor Wiadomość
Rafi
Temat założony przez niniejszego użytkownika
Intergracja Box2D i SFML 2.1
» 2013-11-02 14:52:21
Witam!

Chciałem połączyć ww. biblioteki. O takie coś mi wyszło:
MAIN:
C/C++
#include <SFML/Graphics.hpp>
#include <Box2D/Box2D.h>
#include <iostream>
#include <vector>
#include <Box.h>


using namespace std;


int main()
{
    cout << METERS_PER_PIXEL << endl << PIXELS_PER_METER << endl;
    vector < Box *> pudla;
    float32 timeStep = 1.0f / 60.0f;
    int32 iterations = 10;
    b2World world( b2Vec2( 0, - 9.8f ), true );
   
    { //edge
        b2BodyDef myBodyDef;
        myBodyDef.type = b2_staticBody;
        b2EdgeShape edge;
        edge.Set( b2Vec2( - 100, - 40 ), b2Vec2( 100, - 40 ) );
        b2Body * edgebody = world.CreateBody( & myBodyDef );
       
        edgebody->CreateFixture( & edge, 0 );
    }
    sf::RenderWindow Window( sf::VideoMode( 800, 480 ), "SFML + Box2D" );
   
    while( Window.isOpen() )
    {
        sf::Event Event;
        while( Window.pollEvent( Event ) )
        {
            if( Event.type == sf::Event::Closed )
                 Window.close();
           
            if( Event.type == sf::Event::MouseButtonPressed && Event.mouseButton.button == sf::Mouse::Right )
                 pudla.push_back( new Box( & Window, & world ) );
           
        }
       
        world.Step( timeStep, 8, 3 );
        Window.clear();
        for( int i = 0; i < pudla.size(); i++ )
        {
            pudla[ i ]->Update();
            Window.draw( * pudla[ i ] );
        }
        Window.display();
    }
}
BOX.H:
C/C++
#ifndef BOX_H
#define BOX_H
#include <iostream>
#include <SFML/Graphics.hpp>
#include <Box2D/Box2D.h>

// 1 meter (box2d) is more or less 64 pixels (sfml)
#define RATIO 30.0f
#define PIXELS_PER_METER RATIO

// 64 pixels (sfml) are more or less 1 meter (box2d)
#define UNRATIO (1.0F/RATIO)
#define METERS_PER_PIXEL UNRATIO

#define RADTODEG (b2_pi / 180.0)

using namespace std;

class Box
    : public sf::Drawable
{
public:
    Box( sf::RenderWindow * wnd, b2World * m_world );
    ~Box();
    virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const;
    void Update();
private:
   
    b2Body * body;
    sf::RectangleShape rectangleShape;
};

#endif // BOX_H
BOX.CPP
C/C++
#include "Box.h"

Box::Box( sf::RenderWindow * wnd, b2World * m_world ) //: Window(wnd)
{
    b2BodyDef myBodyDef;
    myBodyDef.position.Set( - 10, - 10 );
    myBodyDef.type = b2_dynamicBody;
    body = m_world->CreateBody( & myBodyDef );
   
    b2PolygonShape boxShape;
    boxShape.SetAsBox( 2 * UNRATIO, 2 * UNRATIO );
   
    b2FixtureDef myFixtureDef;
    myFixtureDef.shape = & boxShape;
    myFixtureDef.density = 1.0f;
    myFixtureDef.restitution = 0.8f;
   
    body->CreateFixture( & myFixtureDef );
   
    body->ResetMassData();
   
    sf::Vector2f sizes( 2 * RATIO, 2 * RATIO );
    rectangleShape = sf::RectangleShape( sizes );
    rectangleShape.setOrigin( rectangleShape.getGlobalBounds().width / 2, rectangleShape.getGlobalBounds().height / 2 );
    rectangleShape.setPosition( 50, 50 );
    rectangleShape.setFillColor( sf::Color::Red );
   
}
void Box::draw( sf::RenderTarget & target, sf::RenderStates states ) const
{
    target.draw( rectangleShape, states );
}
void Box::Update()
{
    float rot = body->GetAngle();
    b2Vec2 pos = body->GetPosition();
   
    rectangleShape.setRotation(( 180 * rot / 3.14 ) ); // przeliczenie radianów na stopnie
    rectangleShape.setPosition( - pos.x * 10, - pos.y * 10 );
    /*cout << "BOX2D " << endl;
        cout << "x : " << pos.x << "y : " << pos.y << endl;
        cout << "SFML " << endl;
        cout << "x : " << rectangleShape.getPosition().x << "y : " << rectangleShape.getPosition().y << endl;*/
}


Box::~Box()
{
    //dtor
}

No i nie dziala to zbyt dobrze. Wydaje mi się że walnąłem się gdzieś przy przeliczaniu pozycji ale nie jestem pewny.
Jakieś propozycje?

Z góry dzięki :)

PS. Jak działają makro RATIO? Przepisałem je z jakiegoś przykładu. Wg. niego 1 metr w Box2D to ok.64 pixeli w SFML, a definicji jest 30.0f?
P-95084
Gabes
» 2013-11-02 16:29:26
C/C++
myBodyDef.position.Set( - 10, - 10 ); // tak nie

*****************************

const int SCREEN_W = 800;
const int SCREEN_H = 600;
const int PIX_METER = 50;
const int CIRCLE = 30;
const int FPS = 60;
// Pamiętać o rzutowaniu nie jakieś tam .około
myBodyDef.position.Set(( float )( SCREEN_W / 2 ) / PIX_METER,( float )( SCREEN_H / 2 ) / PIX_METER );
//
//
//
b2Vec2 pos = dynamicBox->GetPosition(); //Pobieramy pozycję obiektu fizycznego
circle.setPosition( pos.x * PIX_METER, pos.y * PIX_METER );
 
P-95101
Rafi
Temat założony przez niniejszego użytkownika
» 2013-11-02 17:08:56
Nadal nie działa poprawnie.
Gdy zrobię tak jak mi powiedziałeś, tzn.
circle.setPosition( pos.x * PIX_METER, pos.y * PIX_METER );
zamiast mojej wersji, kwadrat leci do góry, choć zgodnie z ustawioną grawitacją powinnien opadać...
P-95109
Gabes
» 2013-11-02 17:11:52
Masz ujemną grawitacje, pozycja każdego obiektu to jego środek.
P-95111
Rafi
Temat założony przez niniejszego użytkownika
» 2013-11-03 10:06:47
Po ustawieniu w testbedzie Box2d takiej samej grawitacji jak w moim świecie kulka opada, więc jakim cudem tutaj, gdy jest grawitacja ujemna, leci do góry?
P-95134
DejaVu
» 2013-11-03 12:40:23
Bo zapewne testbed używa innej biblioteki graficznej, która ma odwróconą oś Y.
P-95150
Rafi
Temat założony przez niniejszego użytkownika
» 2013-11-03 18:04:53
No chyba że tak :D a i dlaczego po spadnięciu kwadratu prawie zawsze on się on obraca? Skoro powinien płasko opaść.
P-95187
Gabes
» 2013-11-03 18:19:23
każdy obiekt ma jakieś domyślne parametry ale możesz je zmienić.
C/C++
///////////CIRCLE///////////////////////
b2BodyDef myCircleDef; //zdefiniowanie jakiegos ciala
myCircleDef.type = b2_dynamicBody; //utworzenie ciala dynamicznego
//  myBodyDef.position.Set(0, 10);   //poz. początkowa ciala
myCircleDef.position.Set(( float )( SCREEN_W / 2 ) / PIX_METER - 4,( float )( SCREEN_H / 2 ) / PIX_METER + 2 );
b2Body * dynamicCircle = world.CreateBody( & myCircleDef ); //kolo
b2CircleShape circleShape;
circleShape.m_p.Set( 0, 0 ); //pozycja względem pozycji ciała
circleShape.m_radius = 0.2; //promień
b2FixtureDef myFixtureDef;
myFixtureDef.shape = & circleShape; //wskaźnik do ciala
myFixtureDef.density = 1.0f; // gestosc
myFixtureDef.friction = 1.0f; // tarcie
myFixtureDef.restitution = 0.6f; //odbicie
dynamicCircle->CreateFixture( & myFixtureDef ); //dodanie param. ciala do kola
dynamicCircle->SetAngularVelocity( 0.0f ); //obroty
b2Vec2 circle_v( 10.0f, - 10.0f ); // wektor dla poz. docelowej
dynamicCircle->SetLinearVelocity( circle_v );
P-95188
« 1 » 2
  Strona 1 z 2 Następna strona