[SFML][BOX2D] Problem z maptile
Ostatnio zmodyfikowano 2014-12-04 08:39
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: 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: 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 ... |
|
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. |
|
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. |
|
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. |
|
1aam2am1 |
» 2014-12-03 15:41:10 A box2d ma 0 na dole i wartości rosną idąc do góry. |
|
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ę. |
|
« 1 » |