pekfos |
» 2024-06-29 19:25:48 W dobrym kierunku zmierzam ? Wziąłeś poprawny kod i go zepsułeś, więc chyba nie. Porównaj sobie ten fragment z oryginałem tu = int( coords.x * tilesInSideMap + x ); tv = int( coords.y * tilesInSideMap + y );
triangles[ 0 ].position = sf::Vector2f( tu * tileSide, tv * tileSide ); triangles[ 1 ].position = sf::Vector2f(( tu + 1 ) * tileSide, tv * tileSide ); triangles[ 2 ].position = sf::Vector2f( tu * tileSide,( tv + 1 ) * tileSide ); triangles[ 3 ].position = sf::Vector2f( tu * tileSide,( tv + 1 ) * tileSide ); triangles[ 4 ].position = sf::Vector2f(( tu + 1 ) * tileSide, tv * tileSide ); triangles[ 5 ].position = sf::Vector2f(( tu + 1 ) * tileSide,( tv + 1 ) * tileSide );
triangles[ 0 ].texCoords = sf::Vector2f( 0, 0 ); triangles[ 1 ].texCoords = sf::Vector2f( 64, 0 ); triangles[ 2 ].texCoords = sf::Vector2f( 0, 64 ); triangles[ 3 ].texCoords = sf::Vector2f( 0, 64 ); triangles[ 4 ].texCoords = sf::Vector2f( 64, 0 ); triangles[ 5 ].texCoords = sf::Vector2f( 64, 64 ); W tym wypadku tu i tv powinno być zerowe, skoro masz na razie jedną grafikę w teksturze. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-06-29 19:36:39 Zdążyłem już zmienić kod. Edytowałem posta. Faktycznie jest to lepsza metoda renderingu gdyż prędkość wzrosła 20x. Poprawiłem tu i tv i teraz działa. Wrzucam kod; 0 ms, 0.000224 s 0 ms, 0.00026 s 0 ms, 0.000228 s 0 ms, 0.000231 s 0 ms, 0.000227 s 0 ms, 0.000227 s 0 ms, 0.000229 s 0 ms, 0.000231 s 0 ms, 0.000226 s 0 ms, 0.000234 s
#ifndef Maps_hpp #define Maps_hpp
float tileSide = 16.0f; int tilesInSideMap = 16; float mapSide = tilesInSideMap * tileSide;
class Tile { public: sf::Vector2i coords; sf::Vector2f position; Texture * texture; sf::Sprite sprite; terrainType ttype; Tile( int x, int y ) { coords.x = x; coords.y = y; ttype = terrainType::grass; texture = getTexture( "assets/tiles/grass" ); } ~Tile() { } void setTerrainType( terrainType ttype ) { this->ttype = ttype; if( ttype == terrainType::grass ) texture = getTexture( "assets/tiles/grass" ); if( ttype == terrainType::sands ) texture = getTexture( "assets/tiles/sands" ); if( ttype == terrainType::water ) texture = getTexture( "assets/tiles/water" ); sprite.setTexture( * texture->texture ); } };
class Map : public sf::Drawable , public sf::Transformable { public: sf::Vector2i coords; std::vector < Tile * > tiles; sf::VertexArray vertexes; Map( int x, int y ) { coords.x = x; coords.y = y; vertexes.setPrimitiveType( sf::Triangles ); vertexes.resize( tilesInSideMap * tilesInSideMap * 6 ); int coord_x, coord_y; int tu, tv; for( int y = 0; y < tilesInSideMap; y++ ) for( int x = 0; x < tilesInSideMap; x++ ) { sf::Vertex * triangles = & vertexes[( x + y * tilesInSideMap ) * 6 ]; coord_x =( coords.x * tilesInSideMap + x ); coord_y =( coords.y * tilesInSideMap + y ); triangles[ 0 ].position = sf::Vector2f( coord_x * tileSide, coord_y * tileSide ); triangles[ 1 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 2 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 3 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 4 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 5 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide,( coord_y + 1 ) * tileSide ); tu = int( coord_x * tileSide ) % 64; tv = int( coord_y * tileSide ) % 64; triangles[ 0 ].texCoords = sf::Vector2f( tu, tv ); triangles[ 1 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 2 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 3 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 4 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 5 ].texCoords = sf::Vector2f( tu + tileSide, tv + tileSide ); } tiles.clear();; for( int y = 0; y < tilesInSideMap; y++ ) for( int x = 0; x < tilesInSideMap; x++ ) { Tile * tile = new Tile( x, y ); tile->position.x = float( coords.x ) * mapSide + float( x ) * tileSide; tile->position.y = float( coords.y ) * mapSide + float( y ) * tileSide; tile->sprite = sf::Sprite(); tile->sprite.setTexture( * tile->texture->texture ); tu = int( tile->position.x ) % tile->texture->texture->getSize().x; tv = int( tile->position.y ) % tile->texture->texture->getSize().y; tile->sprite.setTextureRect( sf::IntRect( tu, tv, tileSide, tileSide ) ); tile->sprite.setPosition( tile->position ); tiles.push_back( tile ); } } ~Map() { } void render() { } private: virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const { states.transform *= getTransform(); states.texture = & * getTexture( "assets/tiles/grass" )->texture; target.draw( vertexes, states ); } };
class World { public: std::vector < Map * > maps; World() { maps.clear(); int start_x = 4; int end_x = 11; int start_y = 7; int end_y = 10; for( int y = start_y; y <= end_y; y++ ) for( int x = start_x; x <= end_x; x++ ) maps.push_back( new Map( x, y ) ); } Map * getMap( sf::Vector2f worldPosition ) { sf::Vector2i mapCoords; mapCoords.x = worldPosition.x / mapSide; mapCoords.y = worldPosition.y / mapSide; Map * map = nullptr; for( auto & m: maps ) { if( m->coords == mapCoords ) map = m; } return map; } Tile * getTile( sf::Vector2f worldPosition ) { Map * map = getMap( worldPosition ); if( map == nullptr ) return nullptr; sf::Vector2i tileCoords; tileCoords.x = int( worldPosition.x ) % int( mapSide ) / tileSide; tileCoords.y = int( worldPosition.y ) % int( mapSide ) / tileSide; return map->tiles[ tileCoords.y * tilesInSideMap + tileCoords.x ]; } void render() { sf::Clock c; sf::Time start = c.getElapsedTime(); for( auto & m: maps ) { window->draw( * m ); } sf::Time end = c.getElapsedTime(); cout <<( end - start ).asMilliseconds() << " ms,\t"; cout <<( end - start ).asSeconds() << " s \n"; } };
World * world;
#endif
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-06-29 19:49:35 Mam jednak jeszcze jedno pytanie. Czy warto w takim przypadku sprawdzać czy mapa jest w zasięgu widzenia kamery/gracza, czy nie ma to żadnego znaczenia - nie wiem dokładnie jak dziedziczy po drawable, transformable a nie chciałbym żeby zacinało przy renderowaniu większej ilości map. |
|
pekfos |
» 2024-06-29 20:52:25 Test na zasięg kamery jest tani, więc pewnie warto. Ale czy będzie to zauważalna optymalizacja, to tego nie wiadomo. Możesz to dodać później, jak pomiary wskażą że warto. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-06-30 14:06:45 Dobra jeszcze jedno pytanie. Jak renderować różne tekstury. Bo próbuję coś zakodzić od dłuższego czasu i mi to nie wychodzi, a w poradniku tego nie ma. Nie mam pojęcia jak to edytować: states.texture = &*getTexture("assets/tiles/grass")->texture; i jak podpiąć teksturę zależną od współrzędnych. class Map : public sf::Drawable , public sf::Transformable { public: sf::Vector2i coords; sf::VertexArray vertexes; sf::Texture textures[ 16 ][ 16 ]; Map( int x, int y ) { coords.x = x; coords.y = y; vertexes.setPrimitiveType( sf::Triangles ); vertexes.resize( 16 * 16 * 6 ); int coord_x, coord_y; int tu, tv; for( int y = 0; y < 16; y++ ) for( int x = 0; x < 16; x++ ) { int r = rand() % 4; if( r == 0 ) textures[ x ][ y ] = * getTexture( "assets/tiles/grass" )->texture; if( r == 1 ) textures[ x ][ y ] = * getTexture( "assets/tiles/sands" )->texture; if( r == 2 ) textures[ x ][ y ] = * getTexture( "assets/tiles/water" )->texture; if( r == 3 ) textures[ x ][ y ] = * getTexture( "assets/tiles/floor" )->texture; sf::Vertex * triangles = & vertexes[( y * 16 + x ) * 6 ]; coord_x =( coords.x * 16 + x ); coord_y =( coords.y * 16 + y ); triangles[ 0 ].position = sf::Vector2f( coord_x * tileSide, coord_y * tileSide ); triangles[ 1 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 2 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 3 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 4 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 5 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide,( coord_y + 1 ) * tileSide ); tu = int( coord_x * tileSide ) % 64; tv = int( coord_y * tileSide ) % 64; triangles[ 0 ].texCoords = sf::Vector2f( tu, tv ); triangles[ 1 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 2 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 3 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 4 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 5 ].texCoords = sf::Vector2f( tu + tileSide, tv + tileSide ); } } ~Map() { } private: virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const { states.transform *= getTransform(); states.texture = & * getTexture( "assets/tiles/grass" )->texture; target.draw( vertexes, states ); } };
|
|
pekfos |
» 2024-06-30 17:34:36 Jak renderować różne tekstury. Bo próbuję coś zakodzić od dłuższego czasu i mi to nie wychodzi, a w poradniku tego nie ma. Nie mam pojęcia jak to edytować: states.texture = &*getTexture("assets/tiles/grass")->texture; i jak podpiąć teksturę zależną od współrzędnych. Tam jest może 5 zdań, ale to akurat jest. Note that we can apply this strategy only if the whole tile set can fit into a single texture. [..] You can download the tileset used for this tilemap example here. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-06-30 17:46:50 Dobra, zrobiłem jak doradziłeś. Zastąpiłem zmienną terrainType odpowiednim przypisywaniem tu, tv. Wszystko działa. tileset: Kod mapy: #ifndef Maps_hpp #define Maps_hpp
float tileSide = 16.0f;
class Map : public sf::Drawable , public sf::Transformable { public: sf::Vector2i coords; sf::VertexArray vertexes; sf::Texture tileset; Map( int x, int y ) { tileset = sf::Texture(); tileset.loadFromFile( "assets/tiles/tileset.png" ); coords.x = x; coords.y = y; vertexes.setPrimitiveType( sf::Triangles ); vertexes.resize( 16 * 16 * 6 ); int coord_x, coord_y; int tu, tv; for( int y = 0; y < 16; y++ ) for( int x = 0; x < 16; x++ ) { sf::Vertex * triangles = & vertexes[( y * 16 + x ) * 6 ]; coord_x =( coords.x * 16 + x ); coord_y =( coords.y * 16 + y ); triangles[ 0 ].position = sf::Vector2f( coord_x * tileSide, coord_y * tileSide ); triangles[ 1 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 2 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 3 ].position = sf::Vector2f( coord_x * tileSide,( coord_y + 1 ) * tileSide ); triangles[ 4 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide, coord_y * tileSide ); triangles[ 5 ].position = sf::Vector2f(( coord_x + 1 ) * tileSide,( coord_y + 1 ) * tileSide ); tu = int( coord_x * tileSide ) % 64; tv = int( coord_y * tileSide ) % 64; triangles[ 0 ].texCoords = sf::Vector2f( tu, tv ); triangles[ 1 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 2 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 3 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 4 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 5 ].texCoords = sf::Vector2f( tu + tileSide, tv + tileSide ); } } void editTile( sf::Vector2f worldMousePosition, int tileNumb = 0 ) { int global_x = worldMousePosition.x / 16; int global_y = worldMousePosition.y / 16; int onMap_x = global_x - coords.x * 16; int onMap_y = global_y - coords.y * 16; if( onMap_x < 0 || onMap_x > 15 || onMap_y < 0 || onMap_y > 15 ) return; sf::Vertex * triangles = & vertexes[( onMap_y * 16 + onMap_x ) * 6 ]; int tu =( int( global_x * tileSide ) % 64 ) +( tileNumb * 64 ); int tv =( int( global_y * tileSide ) % 64 ); cout << "tu: " << tu << ", tv: " << tv << "\n"; triangles[ 0 ].texCoords = sf::Vector2f( tu, tv ); triangles[ 1 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 2 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 3 ].texCoords = sf::Vector2f( tu, tv + tileSide ); triangles[ 4 ].texCoords = sf::Vector2f( tu + tileSide, tv ); triangles[ 5 ].texCoords = sf::Vector2f( tu + tileSide, tv + tileSide ); } ~Map() { } private: virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const { states.transform *= getTransform(); states.texture = & tileset; target.draw( vertexes, states ); } };
class World { public: std::vector < Map * > maps; World() { maps.clear(); int start_x = 0; int end_x = 10; int start_y = 0; int end_y = 10; for( int y = start_y; y <= end_y; y++ ) for( int x = start_x; x <= end_x; x++ ) maps.push_back( new Map( x, y ) ); } Map * getMap( sf::Vector2f worldPosition ) { sf::Vector2i mapCoords; mapCoords.x = worldPosition.x /( 16 * tileSide ); mapCoords.y = worldPosition.y /( 16 * tileSide ); Map * map = nullptr; for( auto & m: maps ) { if( m->coords == mapCoords ) map = m; } return map; } void render() { sf::Clock c; sf::Time start = c.getElapsedTime(); for( auto & m: maps ) { window->draw( * m ); } sf::Time end = c.getElapsedTime(); } };
World * world;
#endif
Użycie: if( !GUIwasClicked && prefabToPaint != nullptr && prefabToPaint->type == gameObjectType::Terrain && sf::Mouse::isButtonPressed( sf::Mouse::Left ) ) { Terrain * terrainPrefab = dynamic_cast < Terrain * >( prefabToPaint ); Map * map = world->getMap( worldMousePosition ); if( map != nullptr ) { if( terrainPrefab->name == "assets/tiles/grass" ) map->editTile( worldMousePosition, 0 ); if( terrainPrefab->name == "assets/tiles/sands" ) map->editTile( worldMousePosition, 1 ); if( terrainPrefab->name == "assets/tiles/water" ) map->editTile( worldMousePosition, 2 ); if( terrainPrefab->name == "assets/tiles/floor" ) map->editTile( worldMousePosition, 3 ); } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-07-14 23:05:41 Chciałbym teraz rozdzielić podłogę(parkiet, płytki etc.) od kafelków(trawa, kamienie, piasek, skały etc.). Podłoga tak samo jak płytki ma mieć rozmiar 16x16 px z użyciem tekstury 64x64 px. Czy dobrym rozwiązaniem będzie stworzenie drugiego vertexarray i dynamicznie przypisywanie do niego elementów ? sf::VertexArray floor; floor.clear(); floor.append( sf::Vertex( position, texCoords ) ); Czy lepiej stworzyć drugą listę statyczną i pole bez podłogi renderować jako transparent w floorset.png (tileset dla podłogi) Jeszcze zastanawiam się nad tym sf::Sprite spr; spr.setTextureRect( sf::IntRect( tu, tv, 16, 16 ) );
|
|
1 « 2 » 3 |