C++ SFML-从纹理加载后,精灵为空

C++ 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()

我正在使用SFML在屏幕上显示精灵。我首先使用纹理并调用loadFromFile()来加载图像。这工作正常,没有错误发生。图像路径似乎是正确的,它加载了图像,但它似乎没有将数据存储在精灵中。精灵显示无误,但显示空白白色图像

以下代码片段中的代码有问题吗?它们应该相当容易阅读:)

我的代码:

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”
使用名称空间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;
        // ...
};