SFML Text repeats across screen

Okay I have 1 problem : http://imgur.com/Q4d8hrm
I don't want the text to display like that, I would like it to Just update in the same position every frame instead of doing what it is doing now.

This is my code (excluding the EventHandler class and stdafx.h)

Graphics.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once

class Graphics
{
public:
	Graphics();
	~Graphics();

	void DisplayLives();

	int playerLives = 200;
	std::stringstream convert;
	std::string dLives;

	sf::Font font;
	sf::Text lives;
};


Graphics.cpp
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
#include "stdafx.h"
#include "Graphics.h"

Graphics::Graphics()
{
}

Graphics::~Graphics()
{
}

void Graphics::DisplayLives()
{
	convert << "Lives = " << playerLives;
	dLives = convert.str();

	if (!font.loadFromFile("arialbd.ttf"))
	{
		std::cout << "Error loading font\n";
	}

	lives.setFont(font);
	lives.setCharacterSize(24);
	lives.setColor(sf::Color::Blue);
	lives.setPosition(0, 0);
	lives.setString(dLives);
}


main.cpp
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
74
75
76
77
78
#include "stdafx.h"
#include "EventHandling.h"
#include "Graphics.h"

EventHandling EH;
Graphics G;

int main()
{
	int WindowWidth = 1280;
	int WindowHeight = 720;
	sf::RenderWindow window(sf::VideoMode(WindowWidth, WindowHeight), "I Love Tiles");
	window.setSize(sf::Vector2u(1152, 648));
	int TileSize = 32;

	std::ifstream openfile("map.txt");

	sf::Texture tileTexture;
	sf::Sprite tiles;

	std::vector<std::vector<sf::Vector2i>> map;
	std::vector<sf::Vector2i> tempMap;
	
	// Load textures into map
	if (openfile.is_open())
	{
		std::string tileLocation;
		openfile >> tileLocation;
		tileTexture.loadFromFile(tileLocation);
		tiles.setTexture(tileTexture);

		while (!openfile.eof())
		{
			std::string str;
			openfile >> str;
			char x = str[0], y = str[2];
			
			if (!isdigit(x) || !isdigit(y))
				tempMap.push_back(sf::Vector2i(-1, -1));
			else
				tempMap.push_back(sf::Vector2i(x - '0', y - '0'));

			if (openfile.peek() == '\n')
			{
				map.push_back(tempMap);
				tempMap.clear();
			}
		}
		map.push_back(tempMap);
	}

	while (window.isOpen())
	{
		// Handle Events
		EH.HandleEvents(window);
		G.DisplayLives();

		// Clears window
		window.clear(sf::Color(0, 255, 255));

		// Draw Map
		for (int i = 0; i < map.size(); i++)
		{
			for (int j = 0; j < map[i].size(); j++)
			{
				if (map[i][j].x != -1 && map[i][j].y != -1)
				{
					tiles.setPosition(j * TileSize, i * TileSize);
					tiles.setTextureRect(sf::IntRect(map[i][j].x * TileSize, map[i][j].y * TileSize, TileSize, TileSize));
					window.draw(tiles);
					window.draw(G.lives);
				}
			}
		}

		window.display();
	}
}


Thanks for any help
Last edited on
Graphcis.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once

class Graphics
{
public:
	Graphics();
	~Graphics();

	void DisplayLives();

	int playerLives = 200;
	std::stringstream convert;
	std::string dLives;

	sf::Font font;
	sf::Text lives;
};


In graphics.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Graphics::DisplayLives()
{
    {
        std::ostringstream oss ;
        oss << "Lives " << playerLives ;
        lives.setString(oss.str());
    }

    if (!font.loadFromFile("arialbd.ttf"))
    {
        std::cout << "Error loading font\n";
    }

    lives.setFont(font);
    lives.setCharacterSize(24);
    lives.setColor(sf::Color::Blue);
    lives.setPosition(0, 0);
}



You should definitely not be attempting to load a font every time this function is called. I would suggest moving the font loading into the constructor, but since you instantiate an object before the renderwindow is created, that isn't a good idea, either. (Although why this needs to be global isn't clear.)
Last edited on
Thanks for the response

Okay well I am unsure of the private and public differences. I have no experience with them.

I don't see how what you did in the {...} fixed my error. It works perfectly now, I'll just have to create my function to change the lives and see if it still works
I don't see how what you did in the {...} fixed my error.


You had:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
#include <sstream>

int main()
{
    int lives = 3;

    std::ostringstream oss;

    for (std::size_t i = 0; i < 5; ++i)
    {
        oss << "Lives " << lives;
        std::cout << oss.str() << '\n';
    }
}
Lives 3
Lives 3Lives 3
Lives 3Lives 3Lives 3
Lives 3Lives 3Lives 3Lives 3
Lives 3Lives 3Lives 3Lives 3Lives 3


I gave you:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <sstream>

int main()
{
    int lives = 3;

    for (std::size_t i = 0; i < 5; ++i)
    {
        std::ostringstream oss;
        oss << "Lives " << lives;
        std::cout << oss.str() << '\n';
    }
}
Lives 3
Lives 3
Lives 3
Lives 3
Lives 3

Sorry I wasn't quite clear with that hahaha, you fixed it. Thanks for that I was just wondering how. Like what did you do that changed, how did putting the ostringstream inside the loop fix my problem?
In the first version of the code there is one ostringstream object that persists until main ends. So, in each iteration of the loop you add stuff to what is already existing in the ostringstream's buffer.

In the second, one ostringstream is constructed and destroyed each iteration of the for loop.
Your sir are a genius, thank you so much :)
Topic archived. No new replies allowed.