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ść
kubawal
Temat założony przez niniejszego użytkownika
[SFML, Box2d] Piłka przelatuje przez statyczną krawędź (b2EdgeShape)
» 2014-01-22 20:24:58
Witam!

W przerwie pisania mojego frameworka Box2d-SFML'owego, dla treningu napisałem sobie prostego pinballa. Jednak, nie wiem czemu piłka przelatuje przez świat niczym nie zważając na krawędzie.

C/C++
#define SCALE 0.05

// 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 );
}

// 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 );
};

void Object::draw( RenderWindow & win )
{
    win.draw( * objSF );
}

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 );
    }
}

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->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.0f;
    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() try
{
    //// świat
    // SF
    RenderWindow win( VideoMode( 800, 800 ), "SFBall" );
   
    // B2
    b2World world( b2Vec2( 0.0f, 9.8f ) );
   
   
    vector < Object *> objs;
    vector < Object *> edges;
   
    //// krawędzie gry
    edges = createGameEdges( & world, & win );
   
    //// piłka
    objs.push_back( createBall( & world, & win ) );
   
    // debugowe info
    cout << "Objs created ->" << endl;
    for( Object *& e: objs )
    {
        cout << "name: " << e->name << endl
        << "size: " << e->objSF->getGlobalBounds().width << " " << e->objSF->getGlobalBounds().height << endl
        << "pos: " << e->objSF->getPosition() << "(SF), " << B2toSF( e->objB2->GetPosition() ) << "(B2)" << endl
        << "center(local): " << getCenter( * e->objSF ) << endl;
    }
    cout << "Total: edges: " << edges.size() << ", objs: " << objs.size() << endl;
   
   
    while( win.isOpen() )
    {
        //...
       
        world.Step( 1.0f / 100.0f, 6, 2 );
       
        // aktualizuj
        for( Object * o: objs )
        {
            o->update();
        }
        for( Object * o: edges )
        {
            o->update();
        }
       
        //...
       
    }
    return 0;
}
(wiem, że mechanizm tworzenia obiektów jest długi i nieelastyczny, ale w końcu po to pisze frameworka, a to jest gra dla zabawy)

PS. sprawdziłem i do świata też jest podpięte 5 obiektów, więc Box je symuluje...
P-102878
kubawal
Temat założony przez niniejszego użytkownika
» 2014-01-23 19:53:46
Myślałem, że na tym forum więcej osób używa Box'a...
P-102997
DejaVu
» 2014-01-23 21:24:17
A czy cokolwiek na scenie Ci koliduje prawidłowo? Może renderowanie sceny nie jest zintegrowane ze stanem faktycznym sceny?

Może ten temat Ci pomoże: http://cpp0x.pl/forum/temat/​?id=9328&p=2.
P-103005
MrPoxipol
» 2014-01-23 21:58:30
Myślałem, że na tym forum więcej osób używa Box'a...
No. Obraź się, bo nikt nie chce Ci odpowiedzieć ;> Pamiętasz co Ci kiedyś napisałem? Nie każdemu chce się szukać w obcym kodzie błędów, każdy ma swoje projekty (no może większość), czas też jest tu ważnym czynnikiem - mało go. (Pozdrawiam serdecznie.)
P-103012
DejaVu
» 2014-01-23 22:09:50
Wklej ten krótki kod konsolowy sobie do projektu i sprawdź jak działa. Zmień go na kulkę i sprawdź czy nadal działa, a potem porównaj różnice ze swoim projektem. Tamten kod który wklejałem działał poprawnie, więc nie wiem czemu widzisz problem w analizie przysłowiowych 30 liniek, prezentujących poprawne działanie kolizji biblioteki Box2D. Dokumentacja jest znacznie dłuższa i jak się przez nią przebijałem rok/dwa lata temu to musiałem przeczytać co najmniej 20 stron, aby uzyskać te 30 linijek działającego pod konsolą kodu.
P-103013
SeaMonster131
» 2014-01-23 22:37:14
Dokumentacja jest znacznie dłuższa i jak się przez nią przebijałem rok/dwa lata temu to musiałem przeczytać co najmniej 20 stron, aby uzyskać te 30 linijek działającego pod konsolą kodu.

Wystarczy skopiować podany kod od strony 7 - Chapter 2 Hello Box2D
http://box2d.org/manual.pdf

Tak czy inaczej, @kubawal, zerknij do tego manuala i może wpadniesz na pomysł co jest nie tak.
P-103016
kubawal
Temat założony przez niniejszego użytkownika
» 2014-01-24 17:03:23
zerknij do tego manuala
W chromie ten adres wyświetla mi się już po wpisaniu b :) (dla użytkowników Mozilli: bardzo często wchodziłem na ten adres)

Zaraz spróbuję jeszcze zrobić debugowe wyświetlanie pozycji obiektu według Box'a i zobaczymy co wyjdzie...

musiałem przeczytać co najmniej 20 stron, aby uzyskać te 30 linijek działającego pod konsolą kodu
Tak apropo, ten kod @DejaVu jest dokładnie taki sam, jak ten w manualu
P-103048
pekfos
» 2014-01-24 17:13:32
Tak apropo, ten kod @DejaVu jest dokładnie taki sam, jak ten w manualu
W 100% identyczny? Nie robiłeś żadnych modyfikacji?

dla użytkowników Mozilli
Huh, jeszcze jedna przeglądarka? Ja tam używam Firefoxa i mi też podpowiada strony po jednym znaku ;)
P-103049
« 1 » 2 3 4
  Strona 1 z 4 Następna strona