【问题标题】:C++ having trouble returning sf::TextureC++ 无法返回 sf::Texture
【发布时间】:2013-10-23 15:46:23
【问题描述】:

我正在尝试将所有纹理存储在一个数组中。但是图像没有返回,这似乎是我的代码

我假设我的 loadTex 和 loadSpri 函数会返回并将它们的数据存储在我创建的数组中,但它似乎没有以这种方式工作,因为当我运行游戏时它们不会出现,只是空白。我的代码可能看起来很糟糕,但我还是个初学者并试图掌握事情的窍门

这里是 render.cpp

#include "render.h"



texandsprite render::textures[5];


sf::Texture loadTex(std::string);
sf::Sprite loadSpri(sf::Texture);

//Function to start the game
void render::start()
{


_mainWindow.create(sf::VideoMode(1024, 768, 32), "A New Life");

textures[1].tex = loadTex("civilian.png");
textures[1].spri = loadSpri(textures[1].tex);
GameLoop();

}



void render::GameLoop()
{


sf::Event event;

//Load(1, "civilian.png");
float x = 0;
float y = 0;

    while(_mainWindow.isOpen())
    {

        while (_mainWindow.pollEvent(event))
        {
            //Check the type of event
            switch (event.type)
            {
                    //window closed
                case sf::Event::Closed:
                    _mainWindow.close();

                    break;

                case sf::Event::KeyPressed:
                    switch(event.key.code)
                    {

                        case sf::Keyboard::Up:
                            --y;
                            break;

                        case sf::Keyboard::Down:
                            y += 5;
                            break;

                        case sf::Keyboard::Right:
                            ++x;
                            break;

                        case sf::Keyboard::Left:
                            --x;
                            break;
                    }



                    break;


                default:

                    break;
            }

        }

    _mainWindow.clear(sf::Color::White);

    //Draw everything here
    //_mainWindow.draw(...);
    textures[1].spri.setPosition(x,y);

    _mainWindow.draw(textures[1].spri);

    //End the current frame
    _mainWindow.display();


    }
}
sf::RenderWindow render::_mainWindow;

sf::Texture render::loadTex(std::string filename)
{
sf::Texture temptex;

if(!temptex.loadFromFile(filename))
{
    std::cout << "Error: could not load image" << filename << std::endl;
}
std::cout << filename << " Loaded" << std::endl;


return temptex;
}

sf::Sprite render::loadSpri(sf::Texture temptex)
{
sf::Sprite tempspri;

tempspri.setTexture(temptex);

return tempspri;
}

这里是 render.h

#ifndef RENDER_H_INCLUDED
#define RENDER_H_INCLUDED

#include "SFML/Window.hpp"
#include "SFML/Graphics.hpp"
#include <iostream>
struct texandsprite
{
    sf::Texture tex;
    sf::Sprite spri;
};


class render
{
public:
    static void start();
    //Here will go a list of all moving entities
    static texandsprite textures[5];
    //Here will go a list of all nonmoving entities
    //static

private:

    static void GameLoop();
    static void Rendering();
    static sf::Texture loadTex(std::string);
    static sf::Sprite loadSpri(sf::Texture);

    static sf::Texture texture;
    static sf::Sprite sprite;
    static sf::RenderWindow _mainWindow;
};


#endif // RENDER_H_INCLUDED

【问题讨论】:

    标签: c++ global-variables sfml


    【解决方案1】:
    sf::Sprite render::loadSpri(sf::Texture temptex)
    {
        sf::Sprite tempspri;
    
        tempspri.setTexture(temptex);
    
        return tempspri;
    }
    

    它与sf::Texture as class member doesn't work? 非常相关。也可以看看my answer there

    发生的情况是,您的精灵设置为显示temptex,但是当函数返回时,该纹理被破坏,因为它是按值传递给函数的。

    您可以改用对sf::Texture 的引用来解决此问题。


    关于您的评论的更多详细信息如下。我稍微简化了您的情况和代码,以突出显示真正需要理解的内容。

    生成带有loadTexture() 的纹理,如下所示,因为只有返回的副本可供用户访问——他无法设置精灵来使用原始纹理,因此他不会遭受白方块综合症的困扰。

    sf::Texture loadTexture(std::string name)
    {
        sf::Texture ret;
        if (!ret.loadFromFile(name)) { doSomethingAboutIt(); }
        return ret;
    }
    

    关于loadSprite() 函数,您可以按如下方式使用sf::Texture 的const ref 来防止任何复制,从而防止出现白方块问题。

    sf::Sprite loadSprite(sf::Texture const& tex)
    {
        sf::Sprite ret(tex);
        return ret;
    }
    

    但是还有一个陷阱:你必须小心你如何存储loadTexture()返回的纹理!这个纹理的生命周期应该和你的精灵的生命周期一样长。你上面的代码(和下面的参考)应该可以工作:

    void render::start()
    {
        _mainWindow.create(sf::VideoMode(1024, 768, 32), "A New Life");
    
        textures[1].tex = loadTexture("civilian.png");
        textures[1].spri = loadSprite(textures[1].tex);
        GameLoop();
    }
    

    【讨论】:

    • 我知道白色方块问题,我想我知道它为什么会发生。是因为当您在函数内部创建纹理时,它只是在该函数本地创建,所以当该函数结束时,分配给它的资源被释放?那会是正确的吗?您能否给我一个代码示例,我不完全理解您将如何去做?谢谢
    • @Joshua 是的,就是这样。我已经更新了我的答案以回答您的评论。 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2013-10-26
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    相关资源
    最近更新 更多