Sprite 在 SFML 中是白色方块
Sprite is white square in SFML
我创建了一个模板,该模板将保存指向任何类型资产的指针及其名为 ResourceHolder 的 ID,但是当我使用指向此模板实例中的纹理的指针将纹理加载到精灵时,它是白色方块。
这是我在 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
然后在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
最后在 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);
}
有问题的代码是 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
以及 Texture
仅存在于 Game
构造函数的本地范围内。一旦执行了构造函数,rh
和 texture
都将 运行 超出范围并且精灵对纹理的引用无效,这导致 white square problem.
我创建了一个模板,该模板将保存指向任何类型资产的指针及其名为 ResourceHolder 的 ID,但是当我使用指向此模板实例中的纹理的指针将纹理加载到精灵时,它是白色方块。 这是我在 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
然后在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
最后在 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);
}
有问题的代码是 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
以及 Texture
仅存在于 Game
构造函数的本地范围内。一旦执行了构造函数,rh
和 texture
都将 运行 超出范围并且精灵对纹理的引用无效,这导致 white square problem.