tBane Temat założony przez niniejszego użytkownika  | 
[SFML] Mapa kafelkowa - czyli jak to zrobić dobrze » 2024-06-24 12:52:28 Witam.  Piszę system mapy kafelkowej i chciałbym to dobrze zrobić. Jakieś rady?  Kod zamieszczam poniżej. #ifndef Maps_hpp #define Maps_hpp
  float tileSide = 32.0f; int tilesInSideMap = 16; float mapSide = tilesInSideMap * tileSide;
  enum class terrainType { grass, sands };
  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" );                  sprite.setTexture( * texture->texture );     } };
  class Map { public:     sf::Vector2i coords;     std::vector < Tile * > tiles;          Map( int x, int y ) {                  coords.x = x;         coords.y = y;                  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 );             tile->sprite.setPosition( tile->position );                          tiles.push_back( tile );         }     }          ~Map() { }          void render() {         for( auto & t: tiles )              window->draw( t->sprite );              } };
  class World { public:     std::vector < Map * > maps;          World() {         maps.clear();                  maps.push_back( new Map( 0, 0 ) );         maps.push_back( new Map( 1, 0 ) );     }          Tile * getTile( 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;                      }                  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() {         for( auto & m: maps ) {             m->render();         }     } };
  World * world;
  #endif
   | 
 | 
tBane Temat założony przez niniejszego użytkownika  | 
» 2024-06-26 13:42:13 Kafelki mapy mają wymiary  16x16 px, a tekstury  64x64 px.  Aby renderować mapę kafelków 16x16 px, używając tekstur o wymiarach 64x64 px, tak aby fragmenty tekstury były wyświetlane w siatce 16x16 px należy: tx = int( tile->position.x ) % tile->texture->texture->getSize().x; ty = int( tile->position.y ) % tile->texture->texture->getSize().y; tile->sprite.setTextureRect( sf::IntRect( tx, ty, tileSide, tileSide ) );
   | 
 | 
DejaVu  | 
» 2024-06-26 13:43:48 Offtopic: Twój projekt zaczyna nieźle wyglądać.  | 
 | 
pekfos  | 
» 2024-06-26 20:18:08 Ile trwa renderowanie? Robienie tego sprajtami jest zwykle wolne.  | 
 | 
tBane Temat założony przez niniejszego użytkownika  | 
» 2024-06-26 21:06:01 Nawet nie mierzyłem, ponieważ renderowało płynnie. Teraz dokonałem pomiaru i wyszło całkiem nieźle. Wyniki dla 24 map (8x4) 16x16 pól: 4 ms,   0.004343 s 4 ms,   0.004179 s 4 ms,   0.004295 s 4 ms,   0.004318 s 4 ms,   0.004167 s 4 ms,   0.004141 s 4 ms,   0.004191 s 4 ms,   0.004175 s 4 ms,   0.004155 s 4 ms,   0.004133 s 4 ms,   0.004223 s 4 ms,   0.004329 s
  (W sumie to mam całkiem dobrą kartę graficzną i może dlatego wyniki są dobre...?) A jest lepsza metoda renderingu map?  | 
 | 
tBane Temat założony przez niniejszego użytkownika  | 
» 2024-06-27 12:51:23 Proporcje budynków szerokość (x) x 16px wysokość h x 16px długość (x/2 + h) x 16px pozostaje jedynie zdecydować czy wszystkie budynki mają mieć tekstury o stałym rozmiarze 256x256 px czy też różne rozmiary wielokrotności 16px. A tak się to prezentuje w edytorze   | 
 | 
pekfos  | 
» 2024-06-27 17:41:18  | 
 | 
tBane Temat założony przez niniejszego użytkownika  | 
» 2024-06-27 19:50:14 Dobra opanowane częściowo: #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 );                          triangles[ 0 ].color = sf::Color::Red;         }                  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 #endif
   | 
 | 
|  « 1 »  2 3 |