Search code examples
c++arraysgraphicssfml

C++ SFML: How to successfully Iteratively render shapes?


I'm looking to iteratively create a set of rectangle shapes of different colours and display them on the screen in different positions. This should produce a maze made up of rectangles.

The positions of the shapes should reflect the array that stores a 9x9 maze.

I'm able to successfully create a single shape, change it's colour and position. However, when I try to do the same to a shape inside an array it does not work. Only a single blue rectangle is generated in the top right corner of the screen.

int main() {

sf::RenderWindow window(sf::VideoMode(1920, 1080), "Baphomet");
sf::RectangleShape tiles[81] = {sf::RectangleShape(sf::Vector2f(20, 20))};

char maze[81] = {0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 1, 0, 1, 0, 1, 1, 1, 0,
                 0, 1, 0, 1, 0, 1, 0, 1, 0,
                 0, 1, 1, 1, 0, 1, 0, 1, 0,
                 0, 0, 0, 1, 0, 1, 0, 1, 0,
                 0, 1, 1, 1, 0, 1, 1, 1, 0,
                 0, 0, 1, 0, 0, 0, 1, 0, 0,
                 0, 0, 1, 1, 1, 1, 1, 1, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0};

int x;
int y;

for (int i = 0; i < 81; i++) {

    if (maze[i] == 0) {
        tiles[i].setFillColor(sf::Color::Blue);
    } else if (maze[i] == 1) {
        tiles[i].setFillColor(sf::Color::Red);
    }

    x = (i % 9) * 20;
    y = (i / 9) * 20;

    std::cout << x  << " " << y << std::endl;

    tiles[i].setPosition((float)x, (float)y);

}

while (window.isOpen())
{
    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
            window.close();
    }

    window.clear();
    for (int i = 0; i < 81; i++) {
        window.draw(tiles[i]);
    }

    window.display();
}

return 0;

}

How can I make the shapes change their positions to the x and y variables successfully?


Solution

  • I think the main problem is the definition

    sf::RectangleShape tiles[81] = {sf::RectangleShape(sf::Vector2f(20, 20))};
    

    Here you explicitly initialize only the first element (tiles[0]). All the rest of the elements will only have default-constructed shape objects.

    To properly initialize all elements to the same values, either use a loop

    for (auto& shape : tiles)
        shape = sf::RectangleShape(sf::Vector2f(20, 20));
    

    Or use a vector

    std::vector<sf::RectangleShape> tiles(81, sf::RectangleShape(sf::Vector2f(20, 20)));