SFML Help - Displaying text in a vertical order with a vector

So im trying to use a vector to display SFML text on the screen, and it works but what i need to do is get the location of the text in the last array and display the current text in the next array below it so it displays underneath, but i cant seem to figure it out, and im asking here because its more of a C++ question than an SFML one.

The first image im manually setting the text location, and in the second image im using the vector to output it. I left all the code in there to manually set it i just commented it out.

This is what it should look like: https://ibb.co/CsVx1MJ
And this is what it does look like: https://ibb.co/JyVPhYM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <SFML/Graphics.hpp>
#include <map>
#include <vector>
#include <iostream>

using std::map;
using std::vector;
using std::make_pair;
using std::pair;

int main()
{
    sf::RenderWindow window(sf::VideoMode(512, 370), "SFML works!");

    sf::Font Arial;
    Arial.loadFromFile("Resources/Fonts/arial.ttf");

    sf::Text ExampleText_1, ExampleText_2;
    ExampleText_1.setFont(Arial);
    ExampleText_1.setCharacterSize(15);
    ExampleText_1.setString("This is basic example text");
    ExampleText_1.setFillColor(sf::Color::White);

    ExampleText_2.setFont(Arial);
    ExampleText_2.setCharacterSize(15);
    ExampleText_2.setString("Test text for the map");
    ExampleText_2.setFillColor(sf::Color::White);

    //This will take in a bunch of sf::Text objects and display them in the box 
    //no matter where it is in a neat uniform fashion.
    vector<sf::Text> textQeue;
  
    textQeue.push_back(ExampleText_1);
    textQeue.push_back(ExampleText_2);

    //ExampleText_1.setPosition(sf::Vector2f(0, 0));
    //ExampleText_2.setPosition(sf::Vector2f(0, 17));

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

            //Prevents contents of window from being stretched
            if (event.type == sf::Event::Resized)
            {
                // update the view to the new size of the window
                sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
                window.setView(sf::View(visibleArea));
            }
        }

        window.clear();

        //Need to figure out how to get position of last text object and set the new text under it with some space
        //between them like regular text.

        for (auto& i : textQeue)
        {
            window.draw(i);
            i.setPosition(sf::Vector2f(0,  textQeue[index + 1].getPosition().y));
        }

        //window.draw(ExampleText_1);
        //window.draw(ExampleText_2);
        window.display();
    }

    return 0;
}
Last edited on
Where is index ever defined?
It might be easier to use a regular for loop if you want to access more than one element on each iteration.

Another option is to define a pointer that keeps track of the "previous element".

Note that in both these cases you need to handle the case when there is no previous element.

Don't forget to increase the y-coordinate by some "line height" amount compared to previous element. You don't want it to be the same.


Another approach would be to just define a variable that keeps track of the current y-coordinate and then increase it by the "line height" on each iteration.


And by the way, should you really be drawing the text before setting its position? I have very little experience with SFML but if I were to guess I would say it should be the other way around.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <SFML/Graphics.hpp>
#include <map>
#include <vector>
#include <iostream>

using std::map;
using std::vector;
using std::make_pair;
using std::pair;

int main()
{
    sf::RenderWindow window(sf::VideoMode(512, 370), "SFML works!");

    sf::Font Arial;
    Arial.loadFromFile("Resources/Fonts/arial.ttf");

    sf::Text ExampleText_1, ExampleText_2;
    ExampleText_1.setFont(Arial);
    ExampleText_1.setCharacterSize(15);
    ExampleText_1.setString("This is basic example text");
    ExampleText_1.setFillColor(sf::Color::White);

    ExampleText_2.setFont(Arial);
    ExampleText_2.setCharacterSize(15);
    ExampleText_2.setString("Test text for the map");
    ExampleText_2.setFillColor(sf::Color::White);

    //This will take in a bunch of sf::Text objects and display them in the box
    //no matter where it is in a neat uniform fashion.
    vector<sf::Text> textQeue;

    textQeue.push_back(ExampleText_1);
    textQeue.push_back(ExampleText_2);

    ExampleText_1.setPosition(sf::Vector2f(0, 0));

    ExampleText_2.setPosition(sf::Vector2f(0, ExampleText_1.getGlobalBounds().height));

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

            //Prevents contents of window from being stretched
            if (event.type == sf::Event::Resized)
            {
                // update the view to the new size of the window
                sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
                window.setView(sf::View(visibleArea));
            }
        }

        window.clear();

        //Need to figure out how to get position of last text object and set the new text under it with some space
        //between them like regular text.



        window.draw(ExampleText_1);
        window.draw(ExampleText_2);
        window.display();
    }

    return 0;
}
This post was written is response to what Yanson wrote before he replaced it with code.

But if he picks a font himself that shouldn't be much of a problem. Using the font size (15), possibly plus some extra padding, will probably work just fine.

If you want to know exactly how big the text is you can call getGlobalBounds() but do you really want lines to have different heights? For example, the text "good" would be higher than "none".
https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1Text.php#ad33ed96ce9fbe99610f7f8b6874a16b4
Last edited on
Yanson wrote:
1
2
ExampleText_1.setPosition(sf::Vector2f(0, 0));
ExampleText_2.setPosition(sf::Vector2f(0, ExampleText_1.getGlobalBounds().height));

Set the text of ExampleText_1 to "__" and you''ll see that this code does not work correctly.

You need to also take ExampleText_1.getGlobalBounds().top into account.
Last edited on
Apparently sf::Text already has multiline support built in.

1
2
3
4
5
sf::Text ExampleText;
ExampleText.setString("This is basic example text\nTest text for the map");
...
window.draw(ExampleText); // This will draw "This is basic example text" and 
                          // "Test text for the map" on two separate lines. 
Last edited on
Topic archived. No new replies allowed.