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

[SFML 2.X] Generowanie Sprajtów Budynków z dachem dwuspadowym

Ostatnio zmodyfikowano 2024-11-09 18:16
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2024-11-06 21:37:14
W sumie to po co? Robisz trade-off na wydajność kosztem pamięci, tylko czy wydajność była tu jakimś problemem? Nie ma co tu mówić o automatyzacji bo nie zastępujesz tu żadnych manualnych czynności. W obu przypadkach wywołujesz funkcję która renderuje budynek, nie ma różnicy jak jest ta funkcja zaimplementowana.
Bo wcześniej miałem teksturę tego domku rysowaną w Paintcie, a teraz teksturę generuję. Chcę uniknąć ręcznego rysowania każdego budynku, gdyż nie jestem w tym dobry i zawsze się myliłem co do różnych wymiarów
P-181832
pekfos
» 2024-11-06 21:42:30
A, czyli jest manualna czynność. No to wtedy ma sens :)
P-181833
tBane
Temat założony przez niniejszego użytkownika
» 2024-11-06 21:52:18
Tak :-) Planuję jeszcze dodać dachówki do tego dachu, tylko jeszcze nie rozplanowałem co i jak. Jutro do tego wrócę bo dziś już sporo napisałem kodu :D

Coś na tej zasadzie (jak sie animuje to odśwież stronę - na początku GIF'u jest cały domek jakby co)
P-181834
tBane
Temat założony przez niniejszego użytkownika
» 2024-11-07 12:08:51
Przerobiłem podstawę dachu - z trójkątów na dwa Quad'y (lewy i prawy). Oraz dodałem generowanie czerwonych dachówek z ciemnoczerwonym outsidem.

Wzorzec:

Rezultat mojego kodu:

C/C++
void loadTexture( std::ifstream & file ) {
   
   
   
   
// check the size
   
cout << size.x << " " << size.y << "\n";
   
   
short walls_height = 3;
   
   
// create basic image to render house
   
sf::Image house_image;
   
house_image.create( size.x * 16,( size.y + walls_height * 2 + 2 ) * 16, sf::Color::Transparent );
   
   
// load the wall texture
   
sf::Image wall;
   
wall.create( 32, 32, sf::Color::Transparent );
   
wall = getTexture( "walls/wooden_wall" )->texture->copyToImage();
   
   
   
// DRAWING A WALLS
   
for( short y = 1; y <= walls_height; y++ ) {
       
for( short x = 0; x < size.x / 2; x++ ) {
           
house_image.copy( wall, x * 2 * 16, house_image.getSize().y - y * 2 * 16 );
       
}
    }
   
   
cout << "\n\n warning! \n";
   
   
// DRAWING A WALLS UNDER THE ROOF
   
short height = size.x / 4;
   
short width = size.x / 2;
   
short start_x;
   
short end_x;
   
   
for( int y = 0; y <= height; y++ ) {
       
start_x = y;
       
end_x = width - y - 1;
       
       
for( int x = 0; x < width; x++ ) {
           
if( x >= start_x && x <= end_x ) {
               
house_image.copy( wall, x * 2 * 16, house_image.getSize().y -( y + walls_height + 1 ) * 2 * 16 );
           
}
        }
    }
   
   
// DRAWING A ROOF
   
sf::Color color = sf::Color( 51, 38, 21 );
   
   
sf::Vector2f p1( 0, walls_height * 2 * 16 );
   
sf::Vector2f p2( size.x / 2 * 16,( walls_height + size.x / 4 ) * 2 * 16 );
   
sf::Vector2f p3( size.x * 16, walls_height * 2 * 16 );
   
sf::Vector2f p4( size.x * 16,( walls_height + size.y / 4 + 1 ) * 2 * 16 );
   
sf::Vector2f p5( size.x / 2 * 16,( walls_height + size.x / 4 + size.y / 4 + 1 ) * 2 * 16 );
   
sf::Vector2f p6( 0,( walls_height + size.y / 4 + 1 ) * 2 * 16 );
   
   
sf::VertexArray left_quad( sf::Quads, 4 );
   
left_quad[ 0 ].position = p1;
   
left_quad[ 1 ].position = p2;
   
left_quad[ 2 ].position = p5;
   
left_quad[ 3 ].position = p6;
   
left_quad[ 0 ].color = color;
   
left_quad[ 1 ].color = color;
   
left_quad[ 2 ].color = color;
   
left_quad[ 3 ].color = color;
   
   
sf::VertexArray right_quad( sf::Quads, 4 );
   
right_quad[ 0 ].position = p2;
   
right_quad[ 1 ].position = p3;
   
right_quad[ 2 ].position = p4;
   
right_quad[ 3 ].position = p5;
   
right_quad[ 0 ].color = color;
   
right_quad[ 1 ].color = color;
   
right_quad[ 2 ].color = color;
   
right_quad[ 3 ].color = color;
   
   
sf::RenderTexture rtex;
   
rtex.create( house_image.getSize().x, house_image.getSize().y );
   
rtex.draw( left_quad );
   
rtex.draw( right_quad );
   
   
// CREATE A TILES
   
   
float tile_width = 16;
   
float tile_height = 8;
   
float tile_border = 2;
   
   
sf::Color color_outside = sf::Color( 128, 48, 48 );
   
sf::Color color_inside = sf::Color::Red;
   
   
for( float y = 0; y <( size.y / 2 + 2 ) * 16; y += tile_height ) {
       
for( float dx = 0; dx < size.x / 2 * 16; dx += tile_width ) {
           
           
float len_of_roof = float( size.x / 4 ) * 2.0f * 16.0f;
           
float dy = len_of_roof / tile_height * float( dx ) / tile_width;
           
           
// outside of tile
           
sf::VertexArray outside( sf::Quads, 4 );
           
outside[ 0 ].position = sf::Vector2f( dx, y + dy +( walls_height ) * 2 * 16 );
           
outside[ 1 ].position = sf::Vector2f( dx + tile_width, y + dy +( walls_height ) * 2 * 16 + tile_height );
           
outside[ 2 ].position = sf::Vector2f( dx + tile_width, y + dy +( walls_height ) * 2 * 16 + 2 * tile_height );
           
outside[ 3 ].position = sf::Vector2f( dx, y + dy +( walls_height ) * 2 * 16 + tile_height );
           
outside[ 0 ].color = color_outside;
           
outside[ 1 ].color = color_outside;
           
outside[ 2 ].color = color_outside;
           
outside[ 3 ].color = color_outside;
           
rtex.draw( outside );
           
           
// inside of tile
           
sf::VertexArray inside( sf::Quads, 4 );
           
inside[ 0 ].position = sf::Vector2f( dx + tile_border, y + dy +( walls_height ) * 2 * 16 + tile_border );
           
inside[ 1 ].position = sf::Vector2f( dx + tile_width - tile_border, y + dy +( walls_height ) * 2 * 16 + tile_height + tile_border );
           
inside[ 2 ].position = sf::Vector2f( dx + tile_width - tile_border, y + dy +( walls_height ) * 2 * 16 + 2 * tile_height - tile_border );
           
inside[ 3 ].position = sf::Vector2f( dx + tile_border, y + dy +( walls_height ) * 2 * 16 + tile_height - tile_border );
           
inside[ 0 ].color = color_inside;
           
inside[ 1 ].color = color_inside;
           
inside[ 2 ].color = color_inside;
           
inside[ 3 ].color = color_inside;
           
rtex.draw( inside );
       
}
    }
   
   
   
sf::Image roof_image = rtex.getTexture().copyToImage();
   
   
house_image.copy( roof_image, 0, 0, sf::IntRect( 0, 0, 0, 0 ), true );
   
   
// create main tex
   
sf::Texture * tex = new sf::Texture();
   
tex->loadFromImage( house_image );
   
   
// create the sprite
   
sprite = sf::Sprite();
   
sprite.setTexture( * tex );
   
sprite.setOrigin( tex->getSize().x / 2, tex->getSize().y );
   
sprite.setPosition( position );
   
}
P-181835
tBane
Temat założony przez niniejszego użytkownika
» 2024-11-07 12:23:35
Coś źle robię, bo dla wartości tile_width = 32, tile_height = 16, kafelki nie są poprawnie rozmieszczanie w pionie. Wydaje mi się, że źle obliczam dy

P-181836
tBane
Temat założony przez niniejszego użytkownika
» 2024-11-07 14:47:18
Udało się. Działa! Tylko dziwne są odstępy dachówek gdy wartość się zmieni z 1 na inną. Zastanawiam się czy pomiędzy ścianami dachu nie zrobić tego przedziału (tej belki) tak jak jest na tym GIF'ie co sądzicie ? I jeszcze muszę zrobić tak by dachówki były rozmieszczone naprzemiennie ..



C/C++
void loadTexture( std::ifstream & file ) {
   
   
   
   
// check the size
   
cout << size.x << " " << size.y << "\n";
   
   
short walls_height = 3;
   
   
// create basic image to render house
   
sf::Image house_image;
   
house_image.create( size.x * 16,( size.y + walls_height * 2 + 2 ) * 16, sf::Color::Transparent );
   
   
// load the wall texture
   
sf::Image wall;
   
wall.create( 32, 32, sf::Color::Transparent );
   
wall = getTexture( "walls/wooden_wall" )->texture->copyToImage();
   
   
   
// DRAWING A WALLS
   
for( short y = 1; y <= walls_height; y++ ) {
       
for( short x = 0; x < size.x / 2; x++ ) {
           
house_image.copy( wall, x * 2 * 16, house_image.getSize().y - y * 2 * 16 );
       
}
    }
   
   
cout << "\n\n warning! \n";
   
   
// DRAWING A WALLS UNDER THE ROOF
   
short height = size.x / 4;
   
short width = size.x / 2;
   
short start_x;
   
short end_x;
   
   
for( int y = 0; y <= height; y++ ) {
       
start_x = y;
       
end_x = width - y - 1;
       
       
for( int x = 0; x < width; x++ ) {
           
if( x >= start_x && x <= end_x ) {
               
house_image.copy( wall, x * 2 * 16, house_image.getSize().y -( y + walls_height + 1 ) * 2 * 16 );
           
}
        }
    }
   
   
// DRAWING A ROOF
   
sf::Color color = sf::Color( 51, 38, 21 );
   
   
sf::Vector2f p1( 0, walls_height * 2 * 16 );
   
sf::Vector2f p2( size.x / 2 * 16,( walls_height + size.x / 4 ) * 2 * 16 );
   
sf::Vector2f p3( size.x * 16, walls_height * 2 * 16 );
   
sf::Vector2f p4( size.x * 16,( walls_height + size.y / 4 + 1 ) * 2 * 16 );
   
sf::Vector2f p5( size.x / 2 * 16,( walls_height + size.x / 4 + size.y / 4 + 1 ) * 2 * 16 );
   
sf::Vector2f p6( 0,( walls_height + size.y / 4 + 1 ) * 2 * 16 );
   
   
sf::VertexArray left_quad( sf::Quads, 4 );
   
left_quad[ 0 ].position = p1;
   
left_quad[ 1 ].position = p2;
   
left_quad[ 2 ].position = p5;
   
left_quad[ 3 ].position = p6;
   
left_quad[ 0 ].color = color;
   
left_quad[ 1 ].color = color;
   
left_quad[ 2 ].color = color;
   
left_quad[ 3 ].color = color;
   
   
sf::VertexArray right_quad( sf::Quads, 4 );
   
right_quad[ 0 ].position = p2;
   
right_quad[ 1 ].position = p3;
   
right_quad[ 2 ].position = p4;
   
right_quad[ 3 ].position = p5;
   
right_quad[ 0 ].color = color;
   
right_quad[ 1 ].color = color;
   
right_quad[ 2 ].color = color;
   
right_quad[ 3 ].color = color;
   
   
sf::RenderTexture rtex;
   
rtex.create( house_image.getSize().x, house_image.getSize().y );
   
rtex.draw( left_quad );
   
rtex.draw( right_quad );
   
   
// CREATE A TILES
   
   
float tiles_rows = 8;
   
float tiles_columns = 8;
   
   
float tile_width = float( size.x ) / 4.0f * 32.0f / tiles_columns;
   
float tile_height = float( size.y / 4 + 1 ) * 32.0f / tiles_rows;
   
float tile_border = 1;
   
   
sf::Color color_outside = sf::Color( 51, 38, 21 );
   
sf::Color color_inside = sf::Color( 128, 24, 24 );
   
   
// LEFT SIDE OF ROOF
   
for( float y = 0; y < tiles_rows; y += 1 ) {
       
for( float x = 0; x < tiles_columns; x += 1 ) {
           
sf::Vector2f quad_pos( x * tile_width, walls_height * 32 + y * tile_height + x * tile_width );
           
           
// outside of tile
           
sf::VertexArray outside( sf::Quads, 4 );
           
outside[ 0 ].position = sf::Vector2f( quad_pos.x, quad_pos.y );
           
outside[ 1 ].position = sf::Vector2f( quad_pos.x + tile_width, quad_pos.y + tile_width );
           
outside[ 2 ].position = sf::Vector2f( quad_pos.x + tile_width, quad_pos.y + tile_width + tile_height );
           
outside[ 3 ].position = sf::Vector2f( quad_pos.x, quad_pos.y + tile_height );
           
outside[ 0 ].color = color_outside;
           
outside[ 1 ].color = color_outside;
           
outside[ 2 ].color = color_outside;
           
outside[ 3 ].color = color_outside;
           
rtex.draw( outside );
           
           
// inside of tile
           
sf::VertexArray inside( sf::Quads, 4 );
           
inside[ 0 ].position = sf::Vector2f( quad_pos.x + tile_border, quad_pos.y + tile_border );
           
inside[ 1 ].position = sf::Vector2f( quad_pos.x + tile_width - tile_border, quad_pos.y + tile_width + tile_border );
           
inside[ 2 ].position = sf::Vector2f( quad_pos.x + tile_width - tile_border, quad_pos.y + tile_width + tile_height - tile_border );
           
inside[ 3 ].position = sf::Vector2f( quad_pos.x + tile_border, quad_pos.y + tile_height - tile_border );
           
inside[ 0 ].color = color_inside;
           
inside[ 1 ].color = color_inside;
           
inside[ 2 ].color = color_inside;
           
inside[ 3 ].color = color_inside;
           
rtex.draw( inside );
       
}
    }
   
   
// RIGHT SIDE OF ROOF
   
for( float y = 0; y < tiles_rows; y += 1 ) {
       
for( float x = 0; x < tiles_columns; x += 1 ) {
           
sf::Vector2f quad_pos( size.x * 16.0f - tile_width - x * tile_width, walls_height * 32 + y * tile_height + x * tile_width );
           
           
// outside of tile
           
sf::VertexArray outside( sf::Quads, 4 );
           
outside[ 0 ].position = sf::Vector2f( quad_pos.x, quad_pos.y + tile_width );
           
outside[ 1 ].position = sf::Vector2f( quad_pos.x + tile_width, quad_pos.y );
           
outside[ 2 ].position = sf::Vector2f( quad_pos.x + tile_width, quad_pos.y + tile_height );
           
outside[ 3 ].position = sf::Vector2f( quad_pos.x, quad_pos.y + tile_width + tile_height );
           
outside[ 0 ].color = color_outside;
           
outside[ 1 ].color = color_outside;
           
outside[ 2 ].color = color_outside;
           
outside[ 3 ].color = color_outside;
           
rtex.draw( outside );
           
           
// inside of tile
           
sf::VertexArray inside( sf::Quads, 4 );
           
inside[ 0 ].position = sf::Vector2f( quad_pos.x + tile_border, quad_pos.y + tile_width + tile_border );
           
inside[ 1 ].position = sf::Vector2f( quad_pos.x + tile_width - tile_border, quad_pos.y + tile_border );
           
inside[ 2 ].position = sf::Vector2f( quad_pos.x + tile_width - tile_border, quad_pos.y + tile_height - tile_border );
           
inside[ 3 ].position = sf::Vector2f( quad_pos.x + tile_border, quad_pos.y + tile_width + tile_height - tile_border );
           
inside[ 0 ].color = color_inside;
           
inside[ 1 ].color = color_inside;
           
inside[ 2 ].color = color_inside;
           
inside[ 3 ].color = color_inside;
           
rtex.draw( inside );
       
}
    }
   
   
   
sf::Image roof_image = rtex.getTexture().copyToImage();
   
   
house_image.copy( roof_image, 0, 0, sf::IntRect( 0, 0, 0, 0 ), true );
   
   
// create main tex
   
sf::Texture * tex = new sf::Texture();
   
tex->loadFromImage( house_image );
   
   
// create the sprite
   
sprite = sf::Sprite();
   
sprite.setTexture( * tex );
   
sprite.setOrigin( tex->getSize().x / 2, tex->getSize().y );
   
sprite.setPosition( position );
   
}
P-181837
pekfos
» 2024-11-07 21:58:39
Zastanawiam się czy pomiędzy ścianami dachu nie zrobić tego przedziału (tej belki) tak jak jest na tym GIF'ie co sądzicie ?
Ja bym dał tam kafel w kształcie ^, bez linii na szczycie. Linia sugeruje że tam jest granica między kaflami, a chcesz mieć je na zakładkę, dlatego na szczycie zawsze jest coś:

No i dobrze żeby dach wystawał poza ścianę trochę, bo będzie zalewać elewację.

Dla estetyki sugerowałbym nie robić quadów z jednym kolorem tylko jakąś grafikę tam wstawić. Na przykład tekstura dachówki, renderowana trochę na zakładkę. A najlepiej miej kilka wariantów tej samej dachówki z różnymi drobnymi defektami i wybieraj je pseudolosowo.
P-181838
tBane
Temat założony przez niniejszego użytkownika
» 2024-11-07 22:05:25
Stopniowo planuję wygenerować ten obrazek samymi kształtami. Jest to możliwe do zrealizowania stąd też rezygnuję ze sprajtów. Jednak chyba dam ten spłaszczony dach na środku - myślę, że jest to prostsze w wykonaniu i lepiej będzie wyglądać. Jak dam belkę o szerokości jednego kafelka to wtedy pozostanie mi po pół kafelka szerokości dla każdego z boków i będę mógł zrobić wystające dachówki :-)

P-181839
1 « 2 » 3 4
Poprzednia strona Strona 2 z 4 Następna strona