tBane Temat założony przez niniejszego użytkownika |
[SFML 2.6.2] Auto-Tiled - Program do rysowania mapy » 2025-07-12 12:43:31 Cześć. Znalazłem algorytm na autotiling. Z tego co rozumiem algorytm jest poprawny jednak nie jestem w stanie przerobić wartości indeksu z 0-256 do 0-15. Pomoże ktoś ? https://codereview.stackexchange.com/questions/257655/algorithm-for-auto-tiling-of-tiles-in-a-2d-tile-map  #ifndef map_hpp #define map_hpp
class Map { public: sf::Vector2f position; std::string data; sf::Vector2i size; std::vector < sf::Sprite > sprites; std::vector < sf::Texture > textures; Map() { data = "################" "################" "##......##...###" "#..##.......####" "####.........###" "######....######" "################" "################"; size = sf::Vector2i( 16, 8 ); position.x =( view.getSize().x - size.x * 32 ) / 2; position.y =( view.getSize().y - size.y * 32 ) / 2; for( int i = 0; i < 16; i++ ) { sf::Texture t; t.loadFromFile( "tex\\" + std::to_string( i ) + ".png" ); textures.push_back( t ); } for( int y = 0; y < size.y; y++ ) { for( int x = 0; x < size.x; x++ ) { char tile = data[ y * size.x + x ]; std::cout << tile; int index = atlasIndexAt( x, y, tile ); sf::Sprite spr = sf::Sprite(); spr.setTexture( textures[ index / 16 ] ); spr.setScale( 0.5f, 0.5f ); spr.setPosition( position.x + 32 * x, position.y + 32 * y ); sprites.push_back( spr ); } std::cout << "\n"; } std::cout << "\n\n"; } ~Map() { } uint8_t atlasIndexAt( uint16_t x, uint16_t y, char tile ) { auto T = tileValueAt( x, y - 1, tile ); auto L = tileValueAt( x - 1, y, tile ); auto R = tileValueAt( x + 1, y, tile ); auto B = tileValueAt( x, y + 1, tile ); auto TL =( T == 0 || L == 0 ) ? 0 : tileValueAt( x - 1, y - 1, tile ); auto TR =( T == 0 || R == 0 ) ? 0 : tileValueAt( x + 1, y - 1, tile ); auto BL =( B == 0 || L == 0 ) ? 0 : tileValueAt( x - 1, y + 1, tile ); auto BR =( B == 0 || R == 0 ) ? 0 : tileValueAt( x + 1, y + 1, tile ); return TL * 1 + T * 2 + TR * 4 + L * 8 + R * 16 + BL * 32 + B * 64 + BR * 128; } uint8_t tileValueAt( uint16_t x, uint16_t y, char tile ) { if( x >= size.x || y >= size.y ) { return 1; } return data[ y * size.x + x ] == tile ? 1: 0; } void draw() { for( auto & tile: sprites ) { window->draw( tile ); } } };
Map * mapa = nullptr;
#endif |
|
pekfos |
» 2025-07-12 17:31:57 nie jestem w stanie przerobić wartości indeksu z 0-256 do 0-15. Pomoże ktoś ? Nie rozumiem jak miałaby działać taka transformacja, algorytm z linku wymaga więcej kombinacji niż 16. Obrazki które załączyłeś pochodzą z innego podejścia do problemu. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-07-12 17:38:57 Już poprawiłem tak by uwzględniało tylko górę, dół, prawo i lewo. Na mój rozum wystarczy dodać bity kafelków i pod koniec wyjdzie wartość z zakresu 0-15? int atlasIndexAt( int x, int y, char tile ) { int index = 0; if( tileValueAt( x, y - 1, tile ) ) index = index | 3; if( tileValueAt( x - 1, y, tile ) ) index = index | 5; if( tileValueAt( x + 1, y, tile ) ) index = index | 10; if( tileValueAt( x, y + 1, tile ) ) index = index | 12; std::cout << x << ", " << y << " : " << index << "\n"; return index; }
to też nie działa. a ja próbuje zsumować binarnie bity czyli 1 + 1 = 1 0 + 1 = 1 1 + 0 = 1 0 + 0 = 0
tak też nie działa :-/ int atlasIndexAt( int x, int y, char tile ) { int index = 0; if( tileValueAt( x, y - 1, tile ) ) index = index ^ 3; if( tileValueAt( x - 1, y, tile ) ) index = index ^ 5; if( tileValueAt( x + 1, y, tile ) ) index = index ^ 10; if( tileValueAt( x, y + 1, tile ) ) index = index ^ 12; std::cout << x << ", " << y << " : " << index << "\n"; return index; }
|
|
pekfos |
» 2025-07-12 18:00:03 Jak już to OR |. Narysuj jak to ma działać. Te sprajty które wstawiłeś wydaje mi się że mają być w przesunięciu pół kafla:  Wtedy jak masz narożnik 0111/1000 to 4 takie narożniki składają się i masz cały jeden kafel w miejscu gdzie miał być kafel z tym typem terenu. Przejścia wychodzą na granicach oryginalnych kafli. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-07-12 18:09:31 Jednak nie działa. Nie działa dla narożników. Dodałem ify ale nie zadziałały:  int atlasIndexAt( int x, int y, char tile ) { int index; if( tile == '#' ) index = 0; else { index = 0; if( tileValueAt( x, y - 1, tile ) ) index = index | 3; if( tileValueAt( x - 1, y, tile ) ) index = index | 5; if( tileValueAt( x + 1, y, tile ) ) index = index | 10; if( tileValueAt( x, y + 1, tile ) ) index = index | 12; if( tileValueAt( x - 1, y - 1, tile ) ) index = index | 1; if( tileValueAt( x + 1, y - 1, tile ) ) index = index | 2; if( tileValueAt( x - 1, y + 1, tile ) ) index = index | 4; if( tileValueAt( x + 1, y + 1, tile ) ) index = index | 8; } return index; }
|
|
pekfos |
» 2025-07-12 18:55:09 Co znaczą te komentarze? Masz 8 warunków, ale w niektórych zapalasz wiele bitów. if( tileValueAt( x, y + 1, tile ) ) index = index | 12; Ten "12-sty" png jest równoznaczny ósmemu i czwartemu razem. Jeśli liczba ma wyjść mniejsza niż 16, to 1, 2, 4, 8 to jedyne liczby jakie możesz zorować i potem jednoznacznie rozdzielić. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-07-12 18:58:13 Chodzi o to, że każdy kafelek jest dzielony na bity 00 00
i próbuje przypisać odpowiednie wartości. Np. takie pole 10 00
ma lewą górną część niebieską. Z kolei 01 01
ma niebieską całą prawą część. Próbuję zsumować wszystkie niebieskie bity i na koniec renderować odpowiedni kafelek. |
|
pekfos |
» 2025-07-12 19:02:04 To znalazłeś dobre obrazki, ale zły kod. Takie kafle są rysowane w siatce przesuniętej o pół kafla względem rzeczywistej mapy, tak jak narysowałem. Wtedy rogi przesuniętych kafli wypadają w środkach pól mapy i bit bierzesz z tego jaki tam jest typ terenu. |
|
« 1 » 2 3 4 5 6 7 8 |