我正在使用SFML在屏幕上显示精灵。我首先使用纹理并调用loadFromFile()加载图像。这很好,不会发生任何错误。图像路径似乎正确并且已加载图像,但似乎未将数据存储在Sprite中。精灵显示无误,但显示空白图像。
以下代码段中的代码是否存在问题?它们应该很容易阅读:)。
我的代码:
Main.cpp
#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
#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);
};
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);
}
答案 0 :(得分:2)
当您调用sf::Sprite
成员函数时,sf::Texture
对象不会在内部复制传递的setTexture()
对象。 sf::Sprite
只是指sf::Texture
;前者不拥有后者。呈现sf::Texture
时,关联的sf::Sprite
必须存在。
sf::Sprite
的文档中对此进行了说明:
请注意,
sf::Sprite
实例不会复制 它使用的纹理,仅保留对其的引用。因此,sf::Texture
使用sf::Sprite
时不得销毁它 (即,永远不要编写使用本地sf::Texture
实例的函数 用于创建精灵)。
问题出在您的Menu
的构造函数中:
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
对象bg
就不复存在了,因为bg
是构造函数内部的局部变量。结果,sf::Sprite
对象background
– Menu
数据成员 –超过了其关联的sf::Texture
对象bg
–本地对象。
然后,在Menu::draw()
中使用此sf::Sprite
对象background
,该对象内部指的是不再存在的sf::Texture
对象:
void Menu::draw(RenderWindow &window) {
window.draw(background, RenderStates::Default);
}
在sf::Texture
的构造函数中,Menu
对象不是 local对象,您可以使其成为{{的 data成员 1}}:
Menu
通过这种方式,class Menu {
// ...
Texture bg;
Sprite background;
// ...
};
拥有Menu
(与以前一样,bg
的构造函数拥有Menu
)因此bg
控制Menu
的生命周期:bg
对象生存期间,bg
被保持活动状态。这次,当您调用Menu
时,Menu::draw()
对象确实引用了一个活跃的sf::Sprite
对象。