C++ SFML-从纹理加载后,精灵为空
我正在使用SFML在屏幕上显示精灵。我首先使用纹理并调用loadFromFile()来加载图像。这工作正常,没有错误发生。图像路径似乎是正确的,它加载了图像,但它似乎没有将数据存储在精灵中。精灵显示无误,但显示空白白色图像 以下代码片段中的代码有问题吗?它们应该相当容易阅读:) 我的代码: Main.cppC++ SFML-从纹理加载后,精灵为空,c++,graphics,textures,sprite,sfml,C++,Graphics,Textures,Sprite,Sfml,我正在使用SFML在屏幕上显示精灵。我首先使用纹理并调用loadFromFile()来加载图像。这工作正常,没有错误发生。图像路径似乎是正确的,它加载了图像,但它似乎没有将数据存储在精灵中。精灵显示无误,但显示空白白色图像 以下代码片段中的代码有问题吗?它们应该相当容易阅读:) 我的代码: Main.cpp #include <SFML/Graphics.hpp> #include "Menu.h" using namespace sf; int main()
#include <SFML/Graphics.hpp>
#include "Menu.h"
using namespace sf;
int main()
{
VideoMode vm = VideoMode::getDesktopMode();
int width = vm.width, height = vm.height;
RenderWindow window(VideoMode(width, height), "Score Arena v1.0", Style::Fullscreen);
window.setPosition(Vector2i(0, 0));
Menu menu(width, height);
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
switch (event.type) {
case Event::Closed:
window.close();
break;
//when a key is pressed
case Event::KeyPressed:
if (Keyboard::isKeyPressed(Keyboard::Escape))
window.close();
break;
}
}
window.clear();
menu.draw(window);
window.display();
}
return 0;
}
#包括
#包括“Menu.h”
使用名称空间sf;
int main()
{
VideoMode vm=VideoMode::getDesktopMode();
int width=vm.width,height=vm.height;
RenderWindow窗口(视频模式(宽度、高度),“Score Arena v1.0”,样式:全屏);
设置位置(向量2i(0,0));
菜单(宽度、高度);
while(window.isOpen())
{
事件;
while(window.pollEvent(事件))
{
开关(事件类型){
案例事件::已结束:
window.close();
打破
//按键时
案例事件::按键:
如果(键盘::isKeyPressed(键盘::Escape))
window.close();
打破
}
}
window.clear();
菜单.绘图(窗口);
window.display();
}
返回0;
}
菜单
#pragma once
#include <string>
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
class Menu {
int page = 0;
string title = "Score Arena";
string labels[4]{
"Single Player",
"Multi Player",
"Options",
"Exit"
};
Sprite background;
int width, height;
public:
Menu(int, int);
void draw(RenderWindow &window);
};
#pragma一次
#包括
#包括
使用名称空间std;
使用名称空间sf;
班级菜单{
int page=0;
string title=“得分竞技场”;
字符串标签[4]{
“单人游戏”,
“多玩家”,
“选项”,
“退出”
};
雪碧背景;
int宽度、高度;
公众:
菜单(int,int);
虚线绘制(渲染窗口和窗口);
};
Menu.cpp
#include "Menu.h"
#include <SFML/Graphics.hpp>
#include <iostream>
Menu::Menu(int width, int height) {
this->width = width;
this->height = height;
Texture bg;
if (!bg.loadFromFile("menuBg.jpg"))
std::cout << "Error loading image!" << std::endl;
background.setTexture(bg);
}
void Menu::draw(RenderWindow &window) {
window.draw(background, RenderStates::Default);
}
#包括“Menu.h”
#包括
#包括
菜单::菜单(整数宽度、整数高度){
这个->宽度=宽度;
这个->高度=高度;
纹理背景;
如果(!bg.loadFromFile(“menuBg.jpg”))
std::cout调用setTexture()时,sf::Sprite
对象不会在内部复制传递的sf::Texture
对象
成员函数。sf::Sprite
仅指sf::Texture
;前者不拥有后者。渲染sf::Sprite
时,关联的sf::Texture
必须存在
文件中规定了:
请务必注意,sf::Sprite
实例不会复制
它使用的纹理只保留对它的引用
sf::Texture
在被sf::Sprite
(即,切勿编写使用本地sf::Texture
实例的函数
用于创建精灵)
问题出在菜单的构造函数中:
Menu::Menu(int width, int height) {
this->width = width;
this->height = height;
Texture bg; // <-- it is local variable !!!
if (!bg.loadFromFile("menuBg.jpg"))
std::cout << "Error loading image!" << std::endl;
background.setTexture(bg); // <-- associating sprite to a local object!!!
// bg goes out of existence!!!
}
可能的解决办法
您可以将菜单
的构造函数中的sf::Texture
对象设置为菜单
的数据成员,而不是本地对象:
class Menu {
// ...
Texture bg;
Sprite background;
// ...
};
这样,Menu
拥有bg
(与之前的情况相反,Menu
的构造函数拥有bg
),因此Menu
控制bg
的生存期:bg
在Menu
对象生存时保持活动状态。这一次,当您调用Menu::draw()
,这个sf::Sprite
对象确实指的是一个活生生的sf::Texture
对象。太好了,非常感谢!我让Texture bg成为Menu.h的一员,这样它就不会再被破坏了!回答得很好!
class Menu {
// ...
Texture bg;
Sprite background;
// ...
};