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

[SFML 2.6.2] Auto-Tiled - Program do rysowania mapy

Ostatnio zmodyfikowano 2025-08-05 06:48
Autor Wiadomość
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




C/C++
#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 =
       
"################"
        "################"
        "##......##...###"
        "#..##.......####"
        "####.........###"
        "######....######"
        "################"
        "################"
;
       
       
/*
  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 );
               
               
//int tex_index = 0 .. 256 -> 0 .. 15
               
               
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  // !map_hpp
P-182704
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.
P-182705
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?

C/C++
int atlasIndexAt( int x, int y, char tile ) {
   
   
int index = 0;
   
   
if( tileValueAt( x, y - 1, tile ) ) index = index | 3; // (3-ci png - cała góra)
   
   
if( tileValueAt( x - 1, y, tile ) ) index = index | 5; // (5-ty png - całe lewo)
   
   
if( tileValueAt( x + 1, y, tile ) ) index = index | 10; // (10-ty png - całe prawo)
   
   
if( tileValueAt( x, y + 1, tile ) ) index = index | 12; // (12-sty png - cały dół)
   
   
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 :-/
C/C++
int atlasIndexAt( int x, int y, char tile ) {
   
   
int index = 0;
   
   
if( tileValueAt( x, y - 1, tile ) ) index = index ^ 3; // (3-ci png)
   
   
if( tileValueAt( x - 1, y, tile ) ) index = index ^ 5; // (5-ty png)
   
   
if( tileValueAt( x + 1, y, tile ) ) index = index ^ 10; // (10-ty png)
   
   
if( tileValueAt( x, y + 1, tile ) ) index = index ^ 12; // (12-sty png)
   
   
std::cout << x << ", " << y << " : " << index << "\n";
   
return index;
}
P-182706
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.
P-182707
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:



C/C++
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; // (3-ci png)
       
       
if( tileValueAt( x - 1, y, tile ) ) index = index | 5; // (5-ty png)
       
       
if( tileValueAt( x + 1, y, tile ) ) index = index | 10; // (10-ty png)
       
       
if( tileValueAt( x, y + 1, tile ) ) index = index | 12; // (12-sty png)
       
       
if( tileValueAt( x - 1, y - 1, tile ) ) index = index | 1; // (1-szy png)
       
       
if( tileValueAt( x + 1, y - 1, tile ) ) index = index | 2; // (2-gi png)
       
       
if( tileValueAt( x - 1, y + 1, tile ) ) index = index | 4; // (4-ty png)
       
       
if( tileValueAt( x + 1, y + 1, tile ) ) index = index | 8; // (8-my png)
       
   
}
   
   
//std::cout << x << ", " << y << " : " << index << "\n";
   
return index;
}
P-182708
pekfos
» 2025-07-12 18:55:09
Co znaczą te komentarze? Masz 8 warunków, ale w niektórych zapalasz wiele bitów.
C/C++
if( tileValueAt( x, y + 1, tile ) ) index = index | 12; // (12-sty png)
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ć.
P-182712
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.
P-182713
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.
P-182714
« 1 » 2 3 4 5 6 7 8
  Strona 1 z 8 Następna strona