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

Obracanie kafelków w mapie kafelkowej sfml

Ostatnio zmodyfikowano 2020-08-06 19:18
Autor Wiadomość
BraveRat
Temat założony przez niniejszego użytkownika
Obracanie kafelków w mapie kafelkowej sfml
» 2020-08-05 18:04:13
Witam ostatnio próbowałem przerobić mapę kafelkową ze strony sfml na taką która będzie zostawiać puste miejsce gdy w tabeli będzie liczba większa niż liczba dostępnych kafelków oraz wedle drugiej tabeli (side) obracać zaznaczone w niej konkretne kafelki. Metoda tworząca mapę:
C/C++
bool MyTileMap::load( sf::Vector2u tileSize, int * tiles, int * side, unsigned int width, unsigned int height, sf::Vector2u tilesetSize )
{
    m_vertices.setPrimitiveType( sf::Quads );
    m_vertices.resize( width * height * 4 );
   
    for( unsigned int i = 0; i < width; i++ )
    {
        for( unsigned int j = 0; j < height; j++ )
        {
            int tileNumber = tiles[ i + j * width ];
           
            int tu = tileNumber %( m_tileset.getSize().x / tileSize.x );
            int tv = tileNumber /( m_tileset.getSize().x / tileSize.x );
           
            sf::Vertex * quad = & m_vertices[( i + j * width ) * 4 ];
           
            quad[ 0 ].position = sf::Vector2f( i * tileSize.x, j * tileSize.y );
            quad[ 1 ].position = sf::Vector2f(( i + 1 ) * tileSize.x, j * tileSize.y );
            quad[ 2 ].position = sf::Vector2f(( i + 1 ) * tileSize.x,( j + 1 ) * tileSize.y );
            quad[ 3 ].position = sf::Vector2f( i * tileSize.x,( j + 1 ) * tileSize.y );
           
            if(( tu * tileSize.x > tilesetSize.x ) ||( tv * tileSize.y > tilesetSize.y ) )
            {
                quad[ 0 ].texCoords = sf::Vector2f( 0, 0 );
                quad[ 1 ].texCoords = sf::Vector2f( 0, 0 );
                quad[ 2 ].texCoords = sf::Vector2f( 0, 0 );
                quad[ 3 ].texCoords = sf::Vector2f( 0, 0 );
            }
            else if( side[ /*TUTAJ*/ ] == 0 )
            {
                quad[ 0 ].texCoords = sf::Vector2f( tu * tileSize.x, tv * tileSize.y );
                quad[ 1 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x, tv * tileSize.y );
                quad[ 2 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x,( tv + 1 ) * tileSize.y );
                quad[ 3 ].texCoords = sf::Vector2f( tu * tileSize.x,( tv + 1 ) * tileSize.y );
            }
            else if( side[ /*I TUTAJ*/ ] == 1 )
            {
                quad[ 1 ].texCoords = sf::Vector2f( tu * tileSize.x, tv * tileSize.y );
                quad[ 0 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x, tv * tileSize.y );
                quad[ 3 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x,( tv + 1 ) * tileSize.y );
                quad[ 2 ].texCoords = sf::Vector2f( tu * tileSize.x,( tv + 1 ) * tileSize.y );
            }
        }
    }
    return true;
}
I w mainie:
C/C++
int bushesPositions[] =
{
    4, 4, 4, 1, 4,
    4, 4, 4, 4, 4,
    4, 3, 4, 4, 4,
    4, 4, 2, 4, 0,
};
int bushesSides[] =
{
    0, 0, 0, 1, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
};
MyTileMap bushes;
bushes.m_tileset.loadFromFile( "bushes.png" );
bushes.load( sf::Vector2u( 299, 218 ), bushesPositions, bushesSides, 5, 4, sf::Vector2u( 1196, 218 ) );
Wstyd się przyznać ale nie wiem co wpisać w miejsca komentarzy by uzyskać ten efekt. Z góry dziękuję.
P-177424
pekfos
» 2020-08-06 15:41:49
Nie powinieneś przypadkiem indeksować side[] tak samo jak tiles[]?

Żeby obrócić grafikę, wystarczy zmienić kolejność przypisania wierzchołków tekstury do wierzchołków geometrii. Tak się akurat składa, że kolejność wierzchołków nie jest dowolna, tylko dookoła obwodu wielokąta, więc zamiast warunków prościej użyć arytmetyki modulo 4 na indeksach.
C/C++
quad[( 0 + obrot ) % 4 ].texCoords = sf::Vector2f( tu * tileSize.x, tv * tileSize.y );
quad[( 1 + obrot ) % 4 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x, tv * tileSize.y );
quad[( 2 + obrot ) % 4 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x,( tv + 1 ) * tileSize.y );
quad[( 3 + obrot ) % 4 ].texCoords = sf::Vector2f( tu * tileSize.x,( tv + 1 ) * tileSize.y );

C/C++
quad[ 0 ].texCoords = sf::Vector2f( 0, 0 );
quad[ 1 ].texCoords = sf::Vector2f( 0, 0 );
quad[ 2 ].texCoords = sf::Vector2f( 0, 0 );
quad[ 3 ].texCoords = sf::Vector2f( 0, 0 );
Tak twoje "puste" pola będą wciąż rysowane i wypełniane kolorem, jaki akurat był pod 0,0 w teksturze. Lepszym sposobem na zostawianie pustych miejsc jest nie rysowanie ich. Jak odwrócisz kolejność pętli, to ta linia
C/C++
sf::Vertex * quad = & m_vertices[( i + j * width ) * 4 ];
będzie równoznaczna z
C/C++
// int licznik = 0;
sf::Vertex * quad = & m_vertices[ licznik * 4 ];
++licznik;
Inkrementuj licznik tylko gdy coś dodałeś do tablicy, a wypełnisz ją tylko rzeczami które są faktycznie do narysowania. Potem wystarczy m_vertices.resize(licznik * 4), by skasować niewykorzystane wierzchołki.
P-177428
BraveRat
Temat założony przez niniejszego użytkownika
» 2020-08-06 19:18:43
Wielkie dzięki
P-177431
« 1 »
  Strona 1 z 1