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

[Box2D & SFML 2.0] Poruszanie "postacią"

Ostatnio zmodyfikowano 2014-05-09 18:44
Autor Wiadomość
PCS
Temat założony przez niniejszego użytkownika
[Box2D & SFML 2.0] Poruszanie "postacią"
» 2014-04-30 23:24:45
Witam, mam pewien problem z którym się męczę, otóż nie będę się rozpisywał, jest on zaprezentowany na tym 13' sekundowym filmiku:
https://www.youtube.com/watch​?v=-BCo2QvXtAU
Jak widać na filmiku, po przytrzymaniu przycisku odpowiadającemu przejście w bok a potem puszczenie jego, "sprite" - grafika jakby wraca do punktu startu, zaś obiekt fizyczny Box2D jest tam gdzie powinien być.

A tutaj kod:
C/C++
#include <SFML\Graphics.hpp>
#include <Box2D\Box2D.h>

/** We need this to easily convert between pixel and real-world coordinates*/
static const float SCALE = 5.f;



/** Create the base for the boxes to land */
void CreateGround( b2World & world, float X, float Y );


/** Create the boxes */
void CreateBox( b2World & world );



int main()
{
    /** Prepare the window */
    sf::RenderWindow window( sf::VideoMode( 800, 600, 32 ), "Test" );
    window.setFramerateLimit( 60 );
   
    /** Prepare the world */
    b2Vec2 gravity( 0.0f, 9.8f );
    bool doSleep = true;
    b2World world( gravity, doSleep );
    CreateGround( world, 400.f, 500.f );
    CreateBox( world );
    int speed = 10;
   
   
   
    /** Prepare textures */
    sf::Texture groundTexture;
    groundTexture.loadFromFile( "ground.png" );
    sf::Texture boxTexture;
    boxTexture.loadFromFile( "box.png" );
   
    sf::Sprite sprite;
    sf::Event event;
   
   
    while( window.isOpen() )
    {
       
        world.Step( 1 / 60.f, 8, 3 );
       
        for( b2Body * BodyIterator = world.GetBodyList(); BodyIterator != 0; BodyIterator = BodyIterator->GetNext() )
        {
           
            if( BodyIterator->GetType() == b2_dynamicBody )
            {
                sprite.setTexture( boxTexture );
                sprite.setOrigin( 16.f, 16.f );
                sprite.setPosition( SCALE * BodyIterator->GetPosition().x, SCALE * BodyIterator->GetPosition().y );
                sprite.setRotation( BodyIterator->GetAngle() * 180 / b2_pi );
               
                if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Right )
                {
                    sprite.move( speed, 0 );
                    speed++;
                }
               
            }
           
            if( BodyIterator->GetType() == b2_staticBody )
            {
               
                sf::Sprite groundSprite;
                groundSprite.setTexture( groundTexture );
                groundSprite.setOrigin( 400.f, 8.f );
                groundSprite.setPosition( BodyIterator->GetPosition().x * SCALE, BodyIterator->GetPosition().y * SCALE );
                window.draw( groundSprite );
            }
        }
       
       
        while( window.pollEvent( event ) )
        {
            if( event.type == sf::Event::Closed )
            {
                window.close();
            }
           
        }
       
        window.draw( sprite );
        window.display();
        window.clear( sf::Color::White );
       
       
    }
   
    return 0;
}

void CreateBox( b2World & world )
{
    b2BodyDef BodyDef;
    BodyDef.position = b2Vec2( 40, 40 );
    BodyDef.type = b2_dynamicBody;
    b2Body * Body = world.CreateBody( & BodyDef );
   
    b2PolygonShape Shape;
    Shape.SetAsBox(( 32.f / 2 ) / SCALE,( 32.f / 2 ) / SCALE );
    b2FixtureDef FixtureDef;
    FixtureDef.density = 1.f;
    FixtureDef.friction = 0.7f;
    FixtureDef.shape = & Shape;
    Body->CreateFixture( & FixtureDef );
}

void CreateGround( b2World & world, float X, float Y )
{
    b2BodyDef BodyDef;
    BodyDef.position = b2Vec2( X / SCALE, Y / SCALE );
    BodyDef.type = b2_staticBody;
    b2Body * Body = world.CreateBody( & BodyDef );
   
    b2PolygonShape Shape;
    Shape.SetAsBox(( 800.f / 2 ) / SCALE,( 16.f / 2 ) / SCALE );
    b2FixtureDef FixtureDef;
    FixtureDef.density = 0.f;
    FixtureDef.shape = & Shape;
    Body->CreateFixture( & FixtureDef );
}

Wiem prawdopodobnie gdzie leży błąd, bodajże w tej linijce:
sprite.setPosition( SCALE * BodyIterator->GetPosition().x, SCALE * BodyIterator->GetPosition().y );
lecz nie mogę dojść jak przełożyć to, aby pozycja "sprite" - pokrywała się z tą fizyczną Box2D, no chyba że nie o to tutaj chodzi. Dzięki z góry za jakąkolwiek pomoc.
P-109010
Gabes
» 2014-05-01 00:55:42
sprite.move( speed, 0 );
daj poza instrukcje if
P-109011
PCS
Temat założony przez niniejszego użytkownika
» 2014-05-01 15:01:31
Jest praktycznie to samo, z tym że pozycja odświeża się szybciej i przy naciśniętym przycisku kwadrat rusza się i powraca do pozycji startowej i tak w kółko, filmik:
https://www.youtube.com/watch​?v=1k9wwyZSWbA
P-109026
pekfos
» 2014-05-01 15:03:24
Czy jak usuniesz grawitację i kolizje, to problem dalej występuje?
P-109027
PCS
Temat założony przez niniejszego użytkownika
» 2014-05-01 15:19:14
Nie bardzo rozumiem, to co podałem na górze to jest cały mój kod, po prostu stworzyłem dwa obiekty fizyczne, jeden static (czyli podłogę) i drugi dynamic (nasz kwadrat) no i po usunięciu tej linijki kodu,
C/C++
sprite.setPosition( SCALE * BodyIterator->GetPosition().x, SCALE * BodyIterator->GetPosition().y );
grawitacji w ogóle nie ma, kwadrat lewituje w górze i tyle - mogę nim poruszać bez problemu w prawo i po puszczeniu przycisku nie wraca na pozycję startową, jak to pokazałem na tych filmikach.
P-109029
pekfos
» 2014-05-01 15:22:21
C/C++
sprite.setPosition( SCALE * BodyIterator->GetPosition().x, SCALE * BodyIterator->GetPosition().y );
//..

if( event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Right )
{
    sprite.move( speed, 0 );
    speed++;
}
Zmieniasz pozycję sprajta, a nie pozycję obiektu w Box2D
P-109030
PCS
Temat założony przez niniejszego użytkownika
» 2014-05-01 15:29:49
Rozumiem, dzięki za wyjaśnienie tyle że nie bardzo wiem jak to ma teraz wyglądać. Jesteś w stanie mi jakoś podpowiedzieć?
P-109031
pekfos
» 2014-05-01 15:35:37
ApplyForce() może.
P-109032
« 1 » 2
  Strona 1 z 2 Następna strona