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

[SFML 2.1, Box2D] Grawitacja działa w inną stronę ? Problem z opadającym klockiem

Ostatnio zmodyfikowano 2014-02-10 16:25
Autor Wiadomość
domin568
Temat założony przez niniejszego użytkownika
[SFML 2.1, Box2D] Grawitacja działa w inną stronę ? Problem z opadającym klockiem
» 2014-02-05 15:40:28
Witam, zaczynam się uczyć biblioteki Box2D, jako pierwszy projekt miałem zamiar napisać aplikacje, w której klocek spada na podłoże. Jednak zachowuje się on dosyć dziwnie :D, zamiast lecieć w dół to on leci w górę. Mój vector grawitacji wygląda tak :
b2Vec2 gravity( 0.0f, 9.8f );
 Moja teoria osi jest taka :
Moja teoria osi
Moja teoria osi
 Więc jeżeli y w moim vectorze grawitacji jest dodatnie (Y>0) to y obiektu powinno wzrastać (Y++). Tutaj dodaję moje debugowe info :
Debugowe Info
Debugowe Info
 Kod :
C/C++
#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include <Box2D/Box2D.h>
#include <iostream>
using namespace std;

const int PixelsPerMeter = 50;


class Kwadrat
{
private:
    sf::RectangleShape kwadrat;
    b2BodyDef bodyDef;
    b2Body * body;
    b2PolygonShape dynamicBox;
    b2FixtureDef fixtureDef;
public:
    Kwadrat( b2World & world )
    {
        kwadrat.setSize( sf::Vector2f( 75, 75 ) );
        kwadrat.setFillColor( sf::Color( 0, 0, 255 ) );
       
        bodyDef.type = b2_dynamicBody;
       
        bodyDef.position.Set( 0.0f, 4.0f ); // czyli y = 200 pixeli na początek
       
        body = world.CreateBody( & bodyDef );
       
        dynamicBox.SetAsBox( 1.25f, 1.25f ); // 1.25 * PixelPerMeter = 75 czyli tyle ile ma kwadrat
       
        fixtureDef.shape = & dynamicBox;
       
        fixtureDef.density = 1.0f;
       
        fixtureDef.friction = 0.3f;
       
        body->CreateFixture( & fixtureDef );
       
    }
   
    void move( int x, int y )
    {
        kwadrat.setPosition( kwadrat.getPosition().x + x, kwadrat.getPosition().y + y );
    }
   
    void rysujKwadrat( sf::RenderWindow & okno )
    {
        okno.draw( kwadrat );
    }
   
    sf::RectangleShape getKwadrat() { return kwadrat; }
   
    void setPosition( sf::Vector2f vektor )
    {
        kwadrat.setPosition( vektor );
    }
    sf::Vector2f getPosition()
    {
        return sf::Vector2f( kwadrat.getPosition().x, kwadrat.getPosition().y );
    }
    b2Body * getBody()
    {
        return body;
    }
};
class ground
{
private:
    sf::RectangleShape groundShape;
    b2BodyDef groundBodyDef;
    b2PolygonShape groundBox;
    b2Body * groundBody;
public:
    ground( b2World & world )
    {
        groundBodyDef.position.Set( 0.0f, 10.0f ); // y = 500 pixeli pozycja podloza
       
        b2Body * groundBody = world.CreateBody( & groundBodyDef );
       
        groundBox.SetAsBox( 50.0f, 10.0f ); // 2500 pixeli x 500 pixeli y
       
        groundBody->CreateFixture( & groundBox, 0.0f );
       
        groundShape.setSize( sf::Vector2f( 50 * PixelsPerMeter, 10 * PixelsPerMeter ) );
       
        groundShape.setPosition( sf::Vector2f( 0, 10 * PixelsPerMeter ) );
       
        groundShape.setFillColor( sf::Color( 255, 0, 0 ) );
    }
    b2Body * getBody() { return groundBody; }
   
    void drawGroundShape( sf::RenderWindow & okno )
    {
        okno.draw( groundShape );
    }
};
struct settingsSimulation
{
    float32 timeStep = 1.0f / 60.0f;
   
    int32 velocityIterations = 6;
   
    int32 positionIterations = 2;
   
};

int _tmain( int argc, _TCHAR * argv[] )
{
    sf::Event zdarzenie;
   
    sf::RenderWindow okno( sf::VideoMode( 800, 600, 32 ), "Projekt z YT", sf::Style::Default );
   
    okno.setFramerateLimit( 60 );
   
    b2Vec2 gravity( 0.0f, 9.8f ); // wektor grawitacji
   
    settingsSimulation ustawienia;
   
    b2World world( gravity );
   
    Kwadrat klocek( world );
   
    ground podloze( world );
   
    while( okno.isOpen() )
    {
        klocek.poruszajFigura( klocek, tablicaPrzyciskowKwadrat );
       
       
        world.Step( ustawienia.timeStep, ustawienia.velocityIterations, ustawienia.positionIterations );
       
        klocek.setPosition( sf::Vector2f( klocek.getBody()->GetPosition().x * PixelsPerMeter, klocek.getBody()->GetPosition().y * PixelsPerMeter ) ); // ustawiam wartości z box2d do klocka z SFML
       
        cout << " X : " << klocek.getPosition().x << " Y : " << klocek.getPosition().y << endl; // y = -63
       
        cout <<( * klocek.getBody() ).GetPosition().x <<( * klocek.getBody() ).GetPosition().y << endl; // y = - 1.26
       
        while( okno.pollEvent( zdarzenie ) )
        {
           
           
        }
        okno.display();
        okno.clear();
        klocek.rysujKwadrat( okno );
        podloze.drawGroundShape( okno );
       
    }
   
    return 0;
}
Liczę na waszą pomoc :)
P-104039
DejaVu
» 2014-02-08 12:25:11
No to dopisz znak minusa przy wyświetlaniu? Albo zrób grawitację ujemną zamiast dodatniej.
P-104238
domin568
Temat założony przez niniejszego użytkownika
» 2014-02-09 14:06:58
Zmieniłem
groundBodyDef.position.Set( 0.0f, 10.0f );
 na
groundBodyDef.position.Set( 0.0f, - 19.0f );
 , Odwróciłem zapisywanie pozycji do SFML'owego kwadratu
C/C++
while( okno.isOpen() )
{
    klocek.setPosition( sf::Vector2f( - klocek.getBody()->GetPosition().x * PixelsPerMeter, - klocek.getBody()->GetPosition().y * PixelsPerMeter ) );
}
 oraz zmieniłem grawitacje na ujemną :
C/C++
b2Vec2 gravity( 0.0f, - 9.8f );
Teraz jest prawie idealnie, jednak musiałem zgadnąć te liczby, a tak nie powinno być... nie zgadza mi się te wartości...
Ale dlaczego gdy poruszam moim klockiem, tak jakby traci wartości fizyczne, i grawitacja go już nie dotyczy, tutaj funkcja ?
C/C++
void move( int x, int y ) // in pixels
{
    body->SetTransform( b2Vec2( body->GetPosition().x + x / PixelsPerMeter, body->GetPosition().y + y / PixelsPerMeter ), body->GetAngle() );
    kwadrat.setPosition( kwadrat.getPosition().x + x, kwadrat.getPosition().y + y );
}
a tu wywołanie :
C/C++
while( okno.isOpen() )
{
    klocek.poruszajFigura( klocek, tablicaPrzyciskowKwadrat );
}
C/C++
void poruszajFigura( T & obiekt, sf::Keyboard::Key tablicaPrzyciskow[] )
{
    if( sf::Keyboard::isKeyPressed( tablicaPrzyciskow[ 0 ] ) )
    {
        obiekt.move( 0, - 50 );
    }
    if( sf::Keyboard::isKeyPressed( tablicaPrzyciskow[ 1 ] ) )
    {
        obiekt.move( 50, 0 );
    }
    if( sf::Keyboard::isKeyPressed( tablicaPrzyciskow[ 2 ] ) )
    {
        obiekt.move( 0, 50 );
    }
    if( sf::Keyboard::isKeyPressed( tablicaPrzyciskow[ 3 ] ) )
    {
        obiekt.move( - 50, 0 );
    }
}
P-104312
DejaVu
» 2014-02-09 20:36:47
Ponieważ teksturę powinieneś renderować na podstawie wartości przechowywanych przez Box2D, a nie samodzielnie je obliczać.
P-104335
domin568
Temat założony przez niniejszego użytkownika
» 2014-02-10 14:01:55
Czyli chodzi o tą linijkę :
klocek.setPosition( sf::Vector2f( klocek.getBody()->GetPosition().x * PixelsPerMeter, klocek.getBody()->GetPosition().y * PixelsPerMeter ) );
 ? Jak mogę renderować teksture na podstawie danych z box2D jeżeli ten operuje na prawdziwych jednostkach (metry,kilometry), a SFML na pikselach ?
P-104376
DejaVu
» 2014-02-10 16:25:02
Tak, chodzi o tą linijkę. Przykład renderowania tekstury na podstawie Box2D znajdziesz w temacie:

http://cpp0x.pl/forum/temat/​?id=9328&p=2
P-104384
« 1 »
  Strona 1 z 1