Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Render a tile Map  (Read 1143 times)

0 Members and 1 Guest are viewing this topic.

AtS

  • Newbie
  • *
  • Posts: 2
    • View Profile
Render a tile Map
« on: March 17, 2015, 03:13:17 am »
Hi everyone, im facing a problem dealing with tile map, things went fine if i load my whole map completely as the tutorial here
bool load(const std::string& tileset, sf::Vector2u tileSize, const int* tiles, unsigned int width, unsigned int height)
    {
        // load the tileset texture
        if (!m_tileset.loadFromFile(tileset))
            return false;

        // resize the vertex array to fit the level size
        m_vertices.setPrimitiveType(sf::Quads);
        m_vertices.resize(width * height * 4);

        // populate the vertex array, with one quad per tile
        for (unsigned int i = 0; i < width; ++i)
            for (unsigned int j = 0; j < height; ++j)
            {
                // get the current tile number
                int tileNumber = tiles[i + j * width];

                // find its position in the tileset texture
                int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                // get a pointer to the current tile's quad
                sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                // define its 4 corners
                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);

                // define its 4 texture coordinates
                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);
            }

        return true;
    }
 
but recently i've appeared to want to load my tile map partial instead of loading all at once, so i modified it a bit to load a fixed rectangle of the map, then i can move the rectangle whenever i want to render the desired scene of the map. Quite simple, i think, but it didnt work, the map to be displayed didnt change after the vertex array already mapped to a difference rectangle. Why would this happen and how to solve it, any opinions would be appreciate, thanks in advance.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: Render a tile Map
« Reply #1 on: March 17, 2015, 07:43:03 am »
The description is unclear (to me). Providing the working code is rather usless, instead you should provide the code that doesn't work. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

AtS

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Render a tile Map
« Reply #2 on: March 17, 2015, 08:29:57 am »
bool MapTexture::loadMap(const std::string& tileset){
        if (test){// when i want to change my tile map i come here
                if (!m_tileset.loadFromFile(tileset)) return false;
        m_vertices.clear(); // i even cleard the array to make sure nothing remains
        m_vertices.setPrimitiveType(sf::Quads);
        unsigned int i,j;
       
        float x = m_map->getSizeMap().x;
        float y = m_map->getSizeMap().y;
        m_vertices.resize(x*y*4);
        for (i = 0; i < x; i++)
                for (j = 5; j < y+5; j++)
                {
                        float tx = m_map->getTileSize().x;
                        float ty = m_map->getTileSize().y;
                        int t = i+j*x;
                        int tileValue = 1;
                        int tCol;
                        if (tileValue <= 0) continue;
                        else{
                                tCol = (tileValue % static_cast<int>(m_tileset.getSize().x/tx)); // calculate position of the texture
//Here i mess things up, it suppose to have a ridiculous look but nothing happens at all
                                sf::Vertex* quad = &m_vertices[(i + j * x - 5*x) * 4];
                                quad[0].position = sf::Vector2f(i*tx,j*ty+5*ty);
                                quad[1].position = sf::Vector2f((i+1)*tx,j*ty+5*ty);
                                quad[2].position = sf::Vector2f((i+1)*tx,(j+1)*ty+5*ty);
                                quad[3].position = sf::Vector2f(i*tx,(j+1)*ty+5*ty);

                                quad[0].texCoords = sf::Vector2f(tCol*tx, 0);
                                quad[1].texCoords = sf::Vector2f((tCol+1)*tx,0);
                                quad[2].texCoords = sf::Vector2f((tCol+1)*tx, 40);
                                quad[3].texCoords = sf::Vector2f(tCol*tx, 40);
                        }
                }
        }
        else{ // normally i come here
                if (!m_tileset.loadFromFile(tileset)) return false;
                m_vertices.setPrimitiveType(sf::Quads);
                unsigned int i,j;
                float x = m_map->getSizeMap().x;
                float y = m_map->getSizeMap().y;
                m_vertices.resize(x*y*4);
                for (i = 0; i < x; i++)
                        for (j = 0; j < y; j++)
                        {
                                float tx = m_map->getTileSize().x;
                                float ty = m_map->getTileSize().y;
                                int t = i+j*x;
                                int tileValue = m_map->getMap()[t];
                                int tCol;
                                if (tileValue <= 0) continue;
                                else{
                                        tCol = (tileValue % static_cast<int>(m_tileset.getSize().x/tx)); // calculate position of the texture
                                        sf::Vertex* quad = &m_vertices[(i + j * x) * 4];
                                        quad[0].position = sf::Vector2f(i*tx,j*ty);
                                        quad[1].position = sf::Vector2f((i+1)*tx,j*ty);
                                        quad[2].position = sf::Vector2f((i+1)*tx,(j+1)*ty);
                                        quad[3].position = sf::Vector2f(i*tx,(j+1)*ty);

                                        quad[0].texCoords = sf::Vector2f(tCol*tx, 0);
                                        quad[1].texCoords = sf::Vector2f((tCol+1)*tx,0);
                                        quad[2].texCoords = sf::Vector2f((tCol+1)*tx, 40);
                                        quad[3].texCoords = sf::Vector2f(tCol*tx, 40);
                                }
                        }
                }
        return true;
};
 

as you can see, when test = true, the test code is executed and actually it did executed, but the nothing changed in my view, i even tried to make some wrong code to make a clearly difference result but nothing happens at all, i have to suppose that when the vertex array is loaded into memory, the gpu cached it somewhere for later use and doesnt refer to the new one anymore, sounds stupid but i have no idea otherwise
« Last Edit: March 17, 2015, 08:32:05 am by AtS »