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

[SFML + Box2d] Problem z b2RevoluteJoint (nie chce się obracać)

Ostatnio zmodyfikowano 2014-02-03 14:32
Autor Wiadomość
kubawal
Temat założony przez niniejszego użytkownika
[SFML + Box2d] Problem z b2RevoluteJoint (nie chce się obracać)
» 2014-01-31 17:27:58
Witam!

Robię sobie prostego pinballa za pomocą Box'a i mam problem z dżointami, których do końca nie rozumiem :)
Mianowicie, nie potrafię dobrze utworzyć obrotowego połączenia na którym flipper będzie się obracał.

C/C++
struct Body
{
    b2Body * b;
    unsigned dm;
    string name;
   
    enum DisplayMethod
    {
        B2DebugDraw,
        Console,
    };
   
    enum Type
    {
        Static,
        Dynamic,
    };
   
    void update();
    void display();
   
    Body( string n, Vector2f pos, b2World * parent, const b2Shape & shape, Type t, unsigned dispMet = B2DebugDraw );
};

struct Game
{
    RenderWindow win;
    b2World world;
    SFMLEngine de; // silnik implementujący b2Draw jako wyświetlanie SFML
    Clock c;
    vector < Body *> objs;
   
    //...
   
    Game( VideoMode vm, b2Vec2 gravity, unsigned displayEng = B2DebugDraw );
   
    Body * addStaticBody( Vector2f centerPos, const b2Shape & shape, string name );
    Body * addDynamicBody( Vector2f centerPos, const b2Shape & shape, string name );
   
    vector < Body *> getBodyList() { return objs; }
    Body * getBody( string name ) { for( int i = 0; i < objs.size(); i++ ) if( objs[ i ]->name == name ) return objs[ i ]; return NULL; }
   
    void update();
    void display();
};

Body::Body( string n, Vector2f pos, b2World * parent, const b2Shape & shape, Type t, unsigned dispMeth )
{
    b2BodyDef def;
    def.position = SFtoB2( pos );
    def.type =( t == Static ) ? b2_staticBody
        : b2_dynamicBody;
    b = parent->CreateBody( & def );
    b->CreateFixture( & shape, 1.0f );
   
    dm = dispMeth;
    name = n;
}

void Body::update()
{
   
}

void Body::display()
{
    if( dm & B2DebugDraw )
        ;
   
    if( dm & Console )
    {
        cout << "Body info: (" << this << ")\n"
        << "Name: " << name << endl
        << "Position (center): " << B2toSF( b->GetPosition() ) << endl
        << "Rotation: " << RDtoDG( b->GetAngle() ) << endl;
    }
}
// implementacji klasy Game nie zamieszczam, bo działa dobrze, jest całkowicie przetestowana)

void createEdges( Game * g ) // tworzy krawędzie gry
{
    // krawędzie gry
    {
        const int vexCnt = 6;
        b2Vec2 vexs[ vexCnt ];
        vexs[ 0 ] = SFtoB2( Vector2f( 300.0f, 700.0f ) );
        vexs[ 1 ] = SFtoB2( Vector2f( 100.0f, 400.0f ) );
        vexs[ 2 ] = SFtoB2( Vector2f( 100.0f, 100.0f ) );
        vexs[ 3 ] = SFtoB2( Vector2f( 600.0f, 100.0f ) );
        vexs[ 4 ] = SFtoB2( Vector2f( 600.0f, 400.0f ) );
        vexs[ 5 ] = SFtoB2( Vector2f( 400.0f, 700.0f ) );
        b2ChainShape edges;
        edges.CreateChain( vexs, vexCnt );
        g->addStaticBody( Vector2f(), edges, "edges" );
    }
   
}

void createFlippers( Game * g ) // tworzy flippery
{
    float flipperLen = 50.0f;
    Body * edges = g->getBody( "edges" );
    // lewy flipper
    {
        b2EdgeShape sh;
        sh.Set( SFtoB2( Vector2f( 250.0f, 650.0f ) ), SFtoB2( Vector2f( 250.0f + flipperLen, 650.0f ) ) );
        Body * flip = g->addDynamicBody( Vector2f(), sh, "left flipper" );
       
        // obrotowe połączenie
        b2RevoluteJointDef rj;
        rj.Initialize( flip->b, edges->b, flip->b->GetWorldCenter() );
        rj.bodyA = flip->b;
        rj.bodyB = edges->b;
        rj.enableLimit = true;
        rj.collideConnected = false;
        rj.lowerAngle = DGtoRD( - 10.0f );
        rj.upperAngle = DGtoRD( 20.0f );
        rj.enableMotor = true;
        rj.motorSpeed = 0.0f;
       
        g->world.CreateJoint( & rj );
    }
}

int main()
{
    Game app( /*...*/ );
    createEdges( & app );
    createFlippers( & app );
   
    // tutaj jeszcze tworze piłkę
   
    while( /*...*/ )
    {
        Event e;
        while( app.win.pollEvent( e ) )
        {
            //...
            if( e.type == Event::KeyPressed && e.key.code == Keyboard::Up )
                (( b2RevoluteJoint * ) app.world.GetJointList() )->SetMotorSpeed( DGtoRD( 10.0f ) ); // trochę nieelastyczne, ale na razie jest tylko 1 joint, więc jest ok
           

Problem jest taki, że flipper nie reaguje na wciśnięcie Up'a, i za nic się nie rusza.

PS. jeszcze małe pytanko: jak zrobić, by flipper był przymocowany nie środkiem, tylko lewym wierzchołkiem?
PPSp. Czy taki sposób tworzenia ciał (pozycja obiektu (0,0), pozycje wierzchołków obiektu są globalne) jest poprawny?

/edit: Tak wygląda scena programu(rysowana za pomocą b2Draw)
P-103710
kubawal
Temat założony przez niniejszego użytkownika
» 2014-02-03 14:32:34
Widzę, że nikt nie odpowiada. No to zamykam...
P-103916
« 1 »
  Strona 1 z 1