SFML рисование элементов вектора указателей - PullRequest
0 голосов
/ 05 ноября 2018

вот структура моей программы:

class Game
{
public:
    unsigned int progressFlags;

    sf::RenderWindow appWindow;
    Screen* currentScreen;

    Game(const unsigned int& width, const unsigned int& height, 
         const unsigned int& bitsPerPixel, const std::string& windowName);
   ~Game();

    void drawScreen();
};

Игра содержит экран, который определяется как:

class Screen
{
public:
    std::vector<sf::Drawable*> sceneElements;
    sf::Sprite backgroundSprite;
    Screen();
    virtual ~Screen();
protected:
    sf::Texture backgroundTexture;  
};

Элементы std :: vector sceneElements собираются с экранов следующим образом:

sceneElements.push_back(&backgroundSprite);

Наконец, я пытаюсь нарисовать все свои графические объекты, используя простой метод:

void Game::drawScreen()
{
    for (unsigned int i = 0; i < currentScreen->sceneElements.size(); i++)
        appWindow.draw(*currentScreen->sceneElements(i));
}

Но appWindow.draw () не работает. Я думаю, что это что-то о разыменовании указателей (некоторые базовые знания C ++, которые я не могу вспомнить), но я не знаю, как это исправить. Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 05 ноября 2018

Я бы просто получил ваши пользовательские классы от sf::Drawable (и, возможно, sf::Transformable). Этот способ рисования иерархически очень прост и в основном выполняется SFML. Следующие фрагменты написаны из памяти; могут быть опечатки. :)

Вам просто нужно создать подкласс вашего Screen класса:

class Screen : public sf::Drawable
{
public:
    std::vector<sf::Drawable*> sceneElements;
    sf::Sprite backgroundSprite;
    Screen();
    virtual ~Screen();
    virtual void draw(sf::RenderTarget &rt, sf::RenderStates states) const;
protected:
    sf::Texture backgroundTexture;  
};

Внутри draw() вы бы просто перебрали все свои элементы (аналогично тому, как вы уже это сделали):

void draw(sf::RenderTarget &rt, sf::RenderStates states) const
{
    for (const auto &e : sceneElements)
        rt.draw(*e, states);
}

Здесь мы разыменовываем один раз, чтобы получить указатель обратно на объект, который затем передается по ссылке (где остальное наследует).

Game::drawScreen() также становится проще:

void Game::drawScreen()
{
    appWindow.draw(*currentScreen);
}

Еще раз разыменование, чтобы перейти от указателя к реальному объекту (передается по ссылке).

Также обратите внимание, что ваш оригинальный дизайн нарушает инкапсуляцию, поскольку Game должен знать, как работать с вещами, которые находятся внутри вашего Scene. Поэтому, если вы что-то измените внутри Scene, вам придется соответственно настроить Game. Используя наследование, вы избегаете этой проблемы.

...