休斯顿,我们遇到了问题。这是一个简化的代码版本:
的main.cpp
#include <SFML/Graphics.hpp>
#include "global.hpp"
#include "init.hpp"
int main(void)
{
createWindow();
loadLevel();
while(window.isOpen())
{
if(!handleEvents()) window.close();
window.clear();
window.draw(bgSprite);
window.display();
}
return 0;
}
global.hpp
sf::Texture bgTexture;
sf::Sprite bgSprite;
init.hpp
void loadGraphics(void)
{
bgTexture.loadFromFile("bg.png");
bgSprite.setTexture(bgTexture);
}
即使纹理和精灵变量是全局的,窗口屏幕仍然是黑色的。 但是,当我将变量放在main()函数中时,一切都很完美。有人可以解释为什么会这样吗?
我认为你可以随时随地调用全局变量,只有当程序本身终止时它们才会消失。
顺便说一下,我也尝试将变量和loadGraphics()放在main()后面(不在头文件中),仍然没有结果。我还注释掉了所有其他代码,所以问题肯定在这里。
我没有调用loadGraphics(函数)。谢谢!我很抱歉你浪费了时间。一切都开始正常。 伤心的哈哈 - 花了1个多小时修理这件事......
答案 0 :(得分:5)
您永远不会致电loadGraphics
。在main
开始时调用它,您的程序可能会正常工作。
但是如果没有全局变量,你几乎肯定会变得更好;并且在任何情况下,您都不希望在标题中定义它们,因为如果您在程序中多次包含该标题,则会破坏单一定义规则。
如果你确实希望它们是全局的,那么在标题中声明它们(不要定义它们):
extern sf::Texture bgTexture;
并在一个源文件中定义它们(就像你已经完成的那样)。
同样,出于同样的原因,您不应在标头中定义非内联函数。将其保留在标题中并使其内联:
inline void loadGraphics() // void parameter is pointless
{
bgTexture.loadFromFile("bg.png");
bgSprite.setTexture(bgTexture);
}
或只是在标题中声明它
void loadGraphics();
并将您的定义移动到源文件中。
您可以通过将它们封装在类中来避免全局变量:
struct Graphics {
Graphics(std::string file) {
texture.loadFromFile(file);
sprite.setTexture(texture);
}
sf::Texture texture;
sf::Sprite sprite;
};
并在main
Graphics graphics("bg.png");
//...
window.draw(graphics.sprite);
答案 1 :(得分:3)
当您将变量global设置为项目时,需要将其放在.cpp文件中并生成.h,将其声明为extern。这允许所有文件引用相同的全局变量。
在您的情况下,您可以更改代码:
<强> global.hpp 强>
extern sf::Texture bgTexture;
extern sf::Sprite bgSprite;
<强> global.cpp 强>
sf::Texture bgTexture;
sf::Sprite bgSprite;
此外,与Mike's answer一样,您永远不会致电loadGraphics()
。
就个人而言,我将其放在另一个.cpp文件中并将.hpp文件放在原型中。
此外,在编译时,您必须将所有cpp文件一起编译为单个可执行文件(即将它们链接在一起)
答案 2 :(得分:1)
bgTexture
和bgSprite
。我在loadGraphics
中看不到您对main
功能的任何来电。
您应该先致电loadGraphics
函数