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

[SFML, Box2d] Piłka przelatuje przez statyczną krawędź (b2EdgeShape)

Ostatnio zmodyfikowano 2014-01-29 20:54
Autor Wiadomość
maly
» 2014-01-26 12:38:33
Skoro i tu i tam nie działa to coś zje...psułeś:)
Najlepiej byłoby gdybyś wrzucił tu kompletny przykład który da się skompilować bo teraz niewiadomo czym jest XLine, YLine i w jaki sposób wyświetlasz objekty.
P-103232
kubawal
Temat założony przez niniejszego użytkownika
» 2014-01-26 13:15:59
No tak, zapomniałem ich też [ctrl-c+ctrl-v] :) Już uzupełniłem. A, i jakby ktoś przeoczył używana jest Box2d 2.3.
P-103237
maly
» 2014-01-26 14:08:12
C/C++
void Object::update()
{
    //if(objB2->GetType() != b2_staticBody)
    {
        objSF->setPosition( B2toSF( objB2->GetPosition() ) /* - getCenter( * objSF )*/ );
        //objSF->setOrigin( getCenter( * objSF ) ); // obrót wokół środka
        objSF->setRotation( RDtoDG( objB2->GetAngle() ) );
        //objSF->setOrigin( 0.0f, 0.0f );
    }
}

Dla box-a w ustawianiu
b2BodyDef::position
 nie używaj
+ getCenter( *...)
C/C++
rightDef.position = SFtoB2( rightPos /* + getCenter( * right->objSF )*/ );

Podłoga jak i pozycja startowa piłki jest chyba w złym miejscu.

Po wprowadzeniu tych zmian piłka zatrzymuje mi się na górnej granicy.

//EDIT
SFtoB2 ma dzielić a B2toSF mnożyć.
P-103249
kubawal
Temat założony przez niniejszego użytkownika
» 2014-01-27 17:55:06
Dla box-a w ustawianiu
C/C++
b2BodyDef::position
 nie używaj
C/C++
+ getCenter( *...)
A Box nie używa czasem środka obiektu jako jego pozycji?
Gdy tak zrobiłem, to zrobił się jeszcze większy burdel(zaraz wrzucę fotkę, żebyście zobaczyli jak to wygląda)

SFtoB2 ma dzielić a B2toSF mnożyć.
A niby czemu?
P-103338
DejaVu
» 2014-01-27 18:08:31
Zamiast korzystać z 'położenia' obiektu polecam podpiąć się bezpośrednio pod punkty obracanych figur, które trzyma wewnętrznie Box2D. Wówczas nie będziesz miał z niczym problemu.
P-103340
kubawal
Temat założony przez niniejszego użytkownika
» 2014-01-27 18:13:40
Czyli mam jako pozycji w SFML używać pozycji środka? W sumie to łatwe, ale później trudno zaprojektować taką scenę, bo wszystkie pozycje trzeba przeliczać z left-top na center...
P-103341
maly
» 2014-01-27 18:22:26
SFtoB2 ma dzielić a B2toSF mnożyć.
A niby czemu?
Trochę przesadziłem z tym ma.

Tak wygląda kod po moich zmianach.
C/C++
#include <SFML/Graphics.hpp>
#include <Box2D/Box2D.h>

//#define SCALE 1 // 1 pixel = 1 metr
#define SCALE 100 // 100 pixeli = 1 metr
//#define SCALE 0.1 // 0.1 pixla = 1 metr

//#include <box2ddebug.h>

using namespace sf;
using namespace std;

// pomocnicza funkcja, zwraca środek obszaru
inline Vector2f getCenter( const FloatRect & r )
{
    return Vector2f( r.width / 2, r.height / 2 );
}

inline Vector2f getCenter( Shape & o )
{
    return getCenter( o.getGlobalBounds() );
}

// konwersja jednostek
inline b2Vec2 SFtoB2( Vector2f vec )
{
    return b2Vec2( vec.x / SCALE, vec.y / SCALE );
}

inline Vector2f B2toSF( b2Vec2 vec )
{
    return Vector2f( vec.x * SCALE, vec.y * SCALE );
}

template < typename Other >
inline Other SFtoB2( Other val )
{
    return val / SCALE;
}

template < typename Other >
inline Other B2toSF( Other val )
{
    return val * SCALE;
}

struct Object
{
    Shape * objSF;
    b2Body * objB2;
    string name;
   
    void update();
    void draw( RenderWindow & win )
    {
        win.draw( * objSF );
    }
};
inline float RDtoDG( float rad ) { return rad *( b2_pi / 180.0f ); }

void Object::update()
{
    //if(objB2->GetType() != b2_staticBody)
    {
        objSF->setPosition( B2toSF( objB2->GetPosition() ) /* - getCenter( * objSF )*/ );
        //objSF->setOrigin( getCenter( * objSF ) ); // obrót wokół środka
        objSF->setRotation( RDtoDG( objB2->GetAngle() ) );
        //objSF->setOrigin( 0.0f, 0.0f );
    }
}

// zwraca rozmiar prostokąta reprezentujący linię poziomą
Vector2f XLine( float len, float w = 1.0f )
{
    return Vector2f( len, w );
}

// zwraca rozmiar prostokąta reprezentujący linię pionową
Vector2f YLine( float len, float w = 1.0f )
{
    return Vector2f( w, len );
}

Object * createBall( b2World * world, RenderWindow * win )
{
    Object * obj = new Object;
   
    obj->name = "ball";
    float objRad = 10.0f;
    Vector2f objPos( 200.0f, 0.0f );
    float objDen = 1.0f;
   
    // SF
    obj->objSF = new CircleShape( objRad );
    obj->objSF->setPosition( objPos );
    obj->objSF->setOrigin( objRad, objRad ); // <<<<<<<<<
    obj->objSF->setFillColor( Color::Red );
   
    // B2
    b2BodyDef objDef;
    objDef.position = SFtoB2( objPos /*+ getCenter( * obj->objSF )*/ );
    objDef.type = b2_dynamicBody;
    objDef.bullet = true;
    b2CircleShape objSh;
    objSh.m_radius = SFtoB2( objRad );
   
    obj->objB2 = world->CreateBody( & objDef );
    obj->objB2->CreateFixture( & objSh, objDen );
   
    return obj;
}

vector < Object *> createGameEdges( b2World * world, RenderWindow * win )
{
    vector < Object *> edges;
    float edW = 2.0f;
   
    //// górna granica
    Object * top = new Object;
    top->name = "top edge";
    edges.push_back( top );
    float topLen = 500.0f;
    Vector2f topPos( 100.0f, 100.0f );
    // SF
    top->objSF = new RectangleShape( XLine( topLen, edW ) );
    top->objSF->setPosition( topPos );
    top->objSF->setOutlineColor( Color::Black );
    top->objSF->setFillColor( Color::Black );
   
    // B2
    b2BodyDef topDef;
    topDef.position = SFtoB2( topPos /* + getCenter( * top->objSF )*/ );
    topDef.type = b2_staticBody;
    b2EdgeShape topSh;
    topSh.Set( b2Vec2(), b2Vec2( SFtoB2( topLen ), 0.0f ) );
    top->objB2 = world->CreateBody( & topDef );
    top->objB2->CreateFixture( & topSh, 1.0f );
   
    //// lewa granica
    Object * left = new Object;
    left->name = "left edge";
    edges.push_back( left );
    float leftLen = 400.0f;
    Vector2f leftPos( 100.0f, 100.0f );
    // SF
    left->objSF = new RectangleShape( YLine( leftLen, edW ) );
    left->objSF->setPosition( leftPos );
    left->objSF->setOutlineColor( Color::Black );
    left->objSF->setFillColor( Color::Black );
   
    // B2
    b2BodyDef leftDef;
    leftDef.position = SFtoB2( leftPos /*+ getCenter( * left->objSF )*/ );
    leftDef.type = b2_staticBody;
    b2EdgeShape leftSh;
    leftSh.Set( b2Vec2(), b2Vec2( SFtoB2( edW ), SFtoB2( leftLen ) ) );
    left->objB2 = world->CreateBody( & leftDef );
    left->objB2->CreateFixture( & leftSh, 1.0f );
   
   
    //// prawa granica
    Object * right = new Object;
    right->name = "right edge";
    edges.push_back( right );
    float rightLen = 400.0f;
    Vector2f rightPos( 600.0f, 100.0f );
   
    // SF
    right->objSF = new RectangleShape( YLine( rightLen, edW ) );
    right->objSF->setPosition( rightPos );
    right->objSF->setOutlineColor( Color::Black );
    right->objSF->setFillColor( Color::Black );
   
    // B2
    b2BodyDef rightDef;
    rightDef.position = SFtoB2( rightPos /* + getCenter( * right->objSF )*/ );
    rightDef.type = b2_staticBody;
    b2EdgeShape rightSh;
    rightSh.Set( b2Vec2(), b2Vec2( SFtoB2( edW ), SFtoB2( rightLen ) ) );
    right->objB2 = world->CreateBody( & rightDef );
    right->objB2->CreateFixture( & rightSh, 1.0f );
   
    //// podłoga
    Object * g = new Object;
    g->name = "ground";
    edges.push_back( g );
    float gLen = 800.f;
    Vector2f gPos( 0.0f, 750.0f );
   
    // SF
    g->objSF = new RectangleShape( XLine( gLen, edW ) );
    g->objSF->setPosition( gPos );
    g->objSF->setOutlineColor( Color::Black );
    g->objSF->setFillColor( Color::Black );
   
    // B2
    b2BodyDef gDef;
    gDef.position = SFtoB2( gPos /*+ getCenter( * g->objSF )*/ );
    gDef.type = b2_staticBody;
    b2EdgeShape gSh;
    gSh.Set( b2Vec2(), b2Vec2( SFtoB2( gLen ), 0.0f ) );
    g->objB2 = world->CreateBody( & gDef );
    g->objB2->CreateFixture( & gSh, 1.0f );
   
    return edges;
}

int main()
{
    //// świat
    // SF
    RenderWindow win( VideoMode( 800, 800 ), "SFBall" );
    // B2
    b2World world( b2Vec2( 0.0f, 9.8f ) );
   
    #ifdef BOX2DDEBUG_H_INCLUDED
    B2dDraw b2Dbg( win );
    b2Dbg.SetFlags( b2Draw::e_shapeBit | b2Draw::e_centerOfMassBit );
    world.SetDebugDraw( & b2Dbg );
    #endif
    vector < Object *> objs;
    vector < Object *> edges;
   
    //// krawędzie gry
    edges = createGameEdges( & world, & win );
   
    //// piłka
    objs.push_back( createBall( & world, & win ) );
   
    while( win.isOpen() )
    {
        //...
        sf::Event event;
        while( win.pollEvent( event ) )
        {
            if( event.type == sf::Event::Closed
            ||( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape ) )
                 win.close();
           
        }
       
        win.clear( sf::Color( 80, 80, 80, 255 ) );
       
        world.Step( 1.0f / 100.0f, 6, 2 );
       
        // aktualizuj
        for( Object * o: objs )
        {
            o->update();
            o->draw( win );
        }
        for( Object * o: edges )
        {
            o->update();
            o->draw( win );
        }
       
        #ifdef BOX2DDEBUG_H_INCLUDED
        world.DrawDebugData();
        #endif
        win.display();
       
        //...
       
    }
    return 0;
}
P-103343
kubawal
Temat założony przez niniejszego użytkownika
» 2014-01-27 19:19:17
Nie no, niby działa, ale jest praktycznie tak sam, jak mój po zmianach zaproponowanych przez Ciebie, a Twój działa A MÓJ NIE...
Aż się chce człowiekowi zastrzelić... Chyba napiszę to od nowa, porządnie bez błędów i jak mi nie wjdzie, to biorę się za jakieś inne zagadnienie...
P-103348
1 2 « 3 » 4
Poprzednia strona Strona 3 z 4 Następna strona