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

[SFML][BOX2D] Problem z maptile

Ostatnio zmodyfikowano 2014-12-04 08:39
Autor Wiadomość
bnk120
Temat założony przez niniejszego użytkownika
[SFML][BOX2D] Problem z maptile
» 2014-12-02 22:38:13
Witam. Mam problem z prawidłowym wygenerowaniem mapy. Kafelki mam rozmiaru 32x32, a poniżej załączam screen z problemem.
 Wygląda to tak jakby ucięło mi połowę każdego kafelka. Co więcej zauważyłem, że przy poruszaniu się po tych kafelkach, postać natrafia na "niewidoczne" przeszkody.
 Kod odpowiedzialny za generowanie map Tile:
C/C++
const float PIXELS_IN_METERS = 30.0f;
//////
for( int width = 0; width < mapTiles.size(); ++width )
{
    for( int height = 0; height < mapTiles[ 0 ].size(); ++height )
    {
        if( mapTiles[ width ].at( height )->type != ft::None )
        {
            ft::Field * type = &( mapTiles[ width ].at( height )->type );
            _spriteList[ width ].at( height ).setTexture( _textureList[ * type ] );
            sf::Vector2f spriteSize( mapTiles[ width ].at( height )->width_tile, mapTiles[ width ].at( height )->height_tile );
            float positionX = height * spriteSize.x;
            float positionY = width * spriteSize.y;
            _spriteList[ width ].at( height ).setOrigin( spriteSize.x / 2, spriteSize.y / 2 );
           
            SetPhysicsBodiesToMapTiles( positionX, positionY, spriteSize.x, spriteSize.y, type );
        }
    }
}

void MapTileRenderModel::SetPhysicsBodiesToMapTiles( float positionX, float positionY, float widthTile, float heightTile, ft::Field * type )
{
    SPhysics * SGamePhysicsWorld = SPhysics::getInstance();
    b2World * _world = SGamePhysicsWorld->GetWorld();
   
    b2BodyDef BodyDef;
    BodyDef.position = b2Vec2( positionX / PIXELS_IN_METERS, positionY / PIXELS_IN_METERS );
    BodyDef.type = b2_staticBody;
    b2Body * Body = _world->CreateBody( & BodyDef );
   
    b2PolygonShape Shape;
    Shape.SetAsBox(( widthTile / 2 ) / PIXELS_IN_METERS,( heightTile / 2 ) / PIXELS_IN_METERS );
    b2FixtureDef FixtureDef;
    FixtureDef.density = 0.0f;
    FixtureDef.friction = 0.3f;
    FixtureDef.shape = & Shape;
    Body->CreateFixture( & FixtureDef );
    Body->SetUserData( type );
}
Kod odpowiedzialny za wyświetlanie pozycji kafelka:
C/C++
for( int width = 0; width < spriteList.size(); ++width )
{
    for( int height = 0; height < spriteList[ 0 ].size(); ++height )
    {
        if( mapTiles[ width ].at( height )->type != ft::None )
        {
            ft::Field * type = & mapTiles[ width ].at( height )->type;
           
            for( b2Body * BodyIterator = _world->GetBodyList(); BodyIterator != 0; BodyIterator = BodyIterator->GetNext() )
            {
                if( BodyIterator->GetUserData() == type )
                {
                    spriteList[ width ][ height ].setPosition( BodyIterator->GetPosition().x * PIXELS_IN_METERS, BodyIterator->GetPosition().y * PIXELS_IN_METERS );
                    _window->draw( spriteList[ width ][ height ] );
                }
            }
        }
    }
}

Przy ustawianiu fizycznego ciała dla postaci nie napotkałem żadnych problemów. Jedynie coś sknociłem przy kafelkach ...
P-122021
maly
» 2014-12-03 08:01:59
Wygląda to tak jakby ucięło mi połowę każdego kafelka
W Box2d pozycja protokąta jest na jego środku a w SFML pozycja sprajta to jego lewy/górny róg, użyj sf::Sprite::setOrigin.

przy poruszaniu się po tych kafelkach, postać natrafia na "niewidoczne" przeszkody
Rogi prostokątów kolidują się ze sobą.
Najprostsze rozwiązanie to zrobienie postaci za pomocą okręgu a nie prostokąta lub podpiąć do dodatkowy okrąg.
Zdecydowanie najlepszym sposobem jest zbudować mapę za pomocą b2EdgeShape lub b2ChainShape i użyć ghost vertices http://www.iforce2d.net/b2dtut​/ghost-vertices.
P-122041
1aam2am1
» 2014-12-03 09:21:10
W Box2d pozycja protokąta jest na jego środku a w SFML pozycja sprajta to jego lewy/górny róg, użyj sf::Sprite::setOrigin.

Od kiedy? Ale ja się nie znam.

Ale wiem że oś y jest odwrócona w sfml co może kolidować z box2d który ma osie normalnie.
P-122044
Hipochondryk
» 2014-12-03 15:32:43
W SFML zawsze prostokąty mają środek na lewym górym rogu. A co do osi Y, to nie wiem co masz na myśli odwrócone, 0 na osi y jest na górze a inne wartości na kolejno w dół, jak na plikach graficznych.
P-122071
1aam2am1
» 2014-12-03 15:41:10
A box2d ma 0 na dole i wartości rosną idąc do góry.
P-122073
bnk120
Temat założony przez niniejszego użytkownika
» 2014-12-04 08:39:16
Dla każdego sprite'a ustawiany jest set origin. Poczytałem o EdgeShape i po zmianach w kodzie faktycznie przyniosło oczekiwany efekt. Jednakże nadal ucinało kafelki, ale po dodaniu do pozycji x i y odpowiednio szerokość i wysokość kafelka mapa elegancko wygenerowała się. Dziwne, bo jak sprawdzałem pozycje każdego kafelka bez dodawania jego rozmiaru, wyglądały na odpowiednie... Cóż EdgeShape rozwiązał problem, reszta to chyba kwestia obliczeń była ;) Dziękuję.
P-122152
« 1 »
  Strona 1 z 1