Ive been trying to work out the best way to manage the drawing of all sprites, text or any sf::Drawable for that matter within my game.
I wanted all the drawables to be displayed stored in a vector so that I can draw them all at once within the main function instead of passing around a reference to the RenderWindow.
To solve this I created a vector of sf::Drawable pointers so that I can fill the vector with the any object that is derived from sf::Drawable
Here is my solution:
main.cpp
#include <vector>
#include "title_screen.h"
int main()
{
sf::RenderWindow window(...);
std::vector<sf::Drawable*> drawBuffer;
TitleScreen titleScreen(window.getSize());
titleScreen.pushDrawablesToVector(drawBuffer);
// Event Handler
while (window.isOpen) {...}
window.clear(sf::Color::White);
for (std::vector<sf::Drawable*>::iterator i = drawBuffer.begin(); i < drawBuffer.end(); i++)
{
window.draw(**i);
}
window.display();
}
title_screen.h
#include <vector>
#include <SFML/Graphics.hpp>
class TitleScreen
{
sf::Text title;
sf::Text newGame;
public:
// Constructor which sets text position using winSize and strings
TitleScreen(sf::Vector2u winSize) {...}
void pushDrawablesToVector(std::vector<sf::Drawable*> &dB)
{
dB.push_back(&title);
dB.push_back(&newGame);
}
};
The code compiles and runs fine, the problem is I get a black white screen without any text.
Im assuming this has something to do with the size of sf::Drawable* vs sf::Text* (and sf::Text private member data not inherited from sf::Drawable).
Any ideas or suggestions?
Thanks in advance
Im assuming this has something to do with the size of sf::Drawable* vs sf::Text* (and sf::Text private member data not inherited from sf::Drawable).
All pointers have the same size (a pointer is a 32 or 64-bit memory address, regardless of what it points to). This would be a problem if you stored sf::Drawable instances and not pointers; in this case the problem is called slicing (you only keep the sf::Drawable members and lose all the derived class' data). But when you copy pointers, you never lose anything.
So there's definitely something wrong in the code that you don't show.
I wanted all the drawables to be displayed stored in a vector so that I can draw them all at once within the main function instead of passing around a reference to the RenderWindow.
What you're trying to avoid would be a much better design. A class should implement services ("draw yourself"), not provide data ("what drawables do you want to draw?"). This is more abstract and intuitive.
By the way, this is a code that works:
#include <SFML/Graphics.hpp>
#include <vector>
int main()
{
sf::RenderWindow window(sf::VideoMode(640, 480), "SFML test");
sf::Font font;
font.loadFromFile("C:/Windows/Fonts/Arial.ttf");
sf::Text text1("hello", font);
sf::Text text2("world", font);
text2.move(0, 50);
std::vector<sf::Drawable*> drawables;
drawables.push_back(&text1);
drawables.push_back(&text2);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
for (std::vector<sf::Drawable*>::const_iterator it = drawables.begin(); it != drawables.end(); ++it)
window.draw(**it);
window.display();
}
return 0;
}