指针向量的 SFML 绘图元素
SFML drawing elements of vector of pointers
这是我的程序的结构:
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++ 知识),但我不知道如何修复它。如果有任何帮助,我将不胜感激。
我只是从 sf::Drawable
(并且可能是 sf::Transformable
)派生出您的自定义 classes。这种分层绘制的方式非常简单,基本上由 SFML 完成。以下片段是凭记忆写的;可能有错别字。 :)
您只需将 class 您的 Screen
class:
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
。使用继承,您可以避免这个问题。
这是我的程序的结构:
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++ 知识),但我不知道如何修复它。如果有任何帮助,我将不胜感激。
我只是从 sf::Drawable
(并且可能是 sf::Transformable
)派生出您的自定义 classes。这种分层绘制的方式非常简单,基本上由 SFML 完成。以下片段是凭记忆写的;可能有错别字。 :)
您只需将 class 您的 Screen
class:
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
。使用继承,您可以避免这个问题。