简体   繁体   中英

Sprite is white square in SFML

I have created template that would hold pointer to any kind of asset and its id called ResourceHolder but when i use pointer to texture from instance of this template to load texture to sprite it is white square. Here is my code in ResourceHolder.hpp:

#ifndef RESOURCEEHOLDER_H
#define RESOURCEHOLDER_H
#include "TexturesId.h"
#include "assert.h"
#include <SFML/Graphics.hpp>
#include <stdexcept>
#include <memory>
#include <string>
#include <map>
using namespace sf;
template<typename Resource,typename Identifier>

class ResourceHolder
{
    public:
        void load(Identifier id,const std::string &filename);
        Resource& get(Identifier id);
        const Resource& get(Identifier id) const;
    protected:

    private:
        std::map<Identifier,std::unique_ptr<Resource>> mResourceMap;
};

#endif // TEXTUREHOLDER_H

Then code in ResourceHolder.cpp

#include "ResourceHolder.h"
using namespace sf;

template<typename Resource,typename Identifier>
void ResourceHolder<Resource,Identifier>::load(Identifier id,const std::string& filename)
{
    std::unique_ptr<Resource> resource(new Resource());
    if(!(resource->loadFromFile(filename)))
       {
           throw std::runtime_error("TextureHolder failed to load " + filename);
       }
    auto inserted=mResourceMap.insert(std::make_pair(id,std::move(resource)));
    assert(inserted.second);
}
template<typename Resource,typename Identifier>
Resource& ResourceHolder<Resource,Identifier>::get(Identifier id)
{
    auto found=mResourceMap.find(id);
    assert(found!=mResourceMap.end());
    return *found->second;
}
template<typename Resource,typename Identifier>
const Resource& ResourceHolder<Resource,Identifier>::get(Identifier id) const
{
    auto found=mResourceMap.find(id);
    assert(found!=mResourceMap.end());
    return *found->second;
}
template class ResourceHolder<Texture,Textures::ID>;

TextureId.h:

#ifndef TEXTURESID_H_INCLUDED
#define TEXTURESID_H_INCLUDED
namespace Textures
{
    enum ID{Landsape,Airplane,Missile};
}

#endif // TEXTURESID_H_INCLUDED

and finally in Game.cpp

Game::Game(int x,int y,std::string &Name)
:window(VideoMode(x,y),Name),texture(),
mPlayer()
{
    ResourceHolder<Texture,Textures::ID> th;
    th.load(Textures::ID::Airplane,"plane.png");
    Texture texture=th.get(Textures::ID::Airplane);
    mPlayer.setTexture(texture);
    mPlayer.setPosition(window.getSize().x/2,window.getSize().y/2);
}

The problematic code is the one in Game.cpp

Game::Game(int x,int y,std::string &Name)
:window(VideoMode(x,y),Name),texture(),
mPlayer()
{
    ResourceHolder<Texture,Textures::ID> th;
    th.load(Textures::ID::Airplane,"plane.png");
    Texture texture=th.get(Textures::ID::Airplane);
    mPlayer.setTexture(texture);
    mPlayer.setPosition(window.getSize().x/2,window.getSize().y/2);
}

ResourceHolder as well as Texture only exist in the local scope of the Game constructor. Once the constructor has been executed, both the rh and texture will run out of scope and the sprite's reference to the texture is invalidated, which leads to the white square problem .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM