【发布时间】:2021-01-04 21:07:45
【问题描述】:
所以,我正在使用 SFML,我正在尝试设置一个实体类和一个继承自它的播放器子类,但这是我第一次使用继承,我遇到了问题: 首先,我有一个 AssetManager 类,我从不同的来源拼凑而成,因为我还不太了解它们是如何工作的:
资产管理器.h:
class AssetManager {
public:
AssetManager();
static sf::Texture& LoadTexture(std::string const& path);
static sf::SoundBuffer& LoadSoundBuffer(std::string const& path);
static sf::Font& LoadFont(std::string const& path);
private:
std::map<std::string, sf::Texture> m_Textures;
std::map<std::string, sf::SoundBuffer> m_SoundBuffers;
std::map<std::string, sf::Font> m_Fonts;
static AssetManager* sInstance;
};
但你只需要看到与纹理相关的部分,这里是 AssetManager.cpp 中的部分:
AssetManager* AssetManager::sInstance = nullptr;
AssetManager::AssetManager() {
assert(sInstance == nullptr);
sInstance = this;
}
sf::Texture& AssetManager::LoadTexture(std::string const& path) {
auto& texMap = sInstance->m_Textures;
auto pairFound = texMap.find(path);
if (pairFound != texMap.end()) {
return pairFound->second;
}
else {
auto& texture = texMap[path];
texture.loadFromFile(path);
return texture;
}
}
然后该类的一个对象包含在Sprite 类中,这有助于为我声明精灵。
Sprite.h:
class Sprite {
public:
AssetManager manager;
sf::Texture m_Texture;
sf::Sprite m_Sprite;
sf::Vector2f sprite_scale;
sf::Vector2u original_size;
sf::Vector2f texture_size;
Sprite(std::string path,sf::IntRect rect,sf::Vector2f size);
};
Sprite.cpp:
Sprite::Sprite(std::string path, sf::IntRect rect, sf::Vector2f size) {
m_Texture = sf::Texture(AssetManager::LoadTexture(path));
m_Sprite.setTextureRect(rect);
m_Sprite.setTexture(m_Texture);
original_size = m_Texture.getSize();
texture_size.x = static_cast<float>(original_size.x);
texture_size.y = static_cast<float>(original_size.y);
sprite_scale.x = size.x / texture_size.x;
sprite_scale.y = size.y / texture_size.y;
m_Sprite.setScale(sf::Vector2f(sprite_scale.x, sprite_scale.y));
m_Sprite.setOrigin(sf::Vector2f(original_size.x / 2, original_size.y / 2));
}
然后,Sprite 类的对象本身包含在 Entity 类中。
Entity.h:
class Entity {
public:
Sprite entity_sprite;
int health;
float speed;
bool collision = false;
bool entity_collision(sf::Sprite entity2_sprite);// Entity.cpp only contains the declaration of this function so far so no need to post it.
};
现在,由于我不明白的原因,我无法在声明 entity_sprite 对象时直接为其分配任何参数,并且我只能在没有参数的情况下声明它,尽管类没有默认构造函数。
但是我可以使用赋值来解决它:
Entity entity_sprite = Entity("res/wildcard.png", { 0,0,36,63 }, { 36,63 });
但这不是主要问题,直接使用Entity 类不是我想要做的,我正在尝试编写Player 子类并改用它:
Player.h:
class Player:public Entity {
Player() {
entity_sprite = Sprite("res/wildcard.png", { 0,0,36,63 }, { 36,63 });
}
};
现在我再次无法直接将参数直接分配给对象,因为call of an object of a class type without appropriate operator() or conversion function to pointer-to-function type(如果我回到Entity 对象并在那里分配参数并假装错误没有存在,Player类产生的错误变为Too many arguments' and 'Too many initializers
这太令人困惑了。
尽管如此,我再次能够使用赋值来绕过它,与以前完全相同,只是这次我收到错误消息 the default constructor "Entity" cannot be referenced -- its a deleted function.,所以我回到 Entity 类并添加一个空构造函数像这样:Entity() { } 但是这个构造函数给了我另一个错误说no default constructor exists for class "Sprite",即使 Entity 类并不完全继承自 Sprite 类,所以我更进一步回到 Sprite 类并给它一个空的构造函数:Sprite(){},错误似乎消失了,直到我在main.cpp 文件中声明一个Player 对象并尝试编译并获得指向AssetManager.cpp 中以下行的调试错误:assert(sInstance == nullptr);
这么看似简单的任务却遇到这么多问题,我该如何摆脱困境?
【问题讨论】:
-
即使 Entity 类并不完全继承自 Sprite 类它也不必。它有一个
Sprite类型的字段,所以它需要知道如何构造这样一个字段。您添加构造函数并没有解决任何问题,因为编译器正在删除构造函数,因为Sprite的潜在问题 - 所以您必须确保值持有的所有类型都是可构造的。 -
您能否提供一个产生错误的代码示例?您在最后两段中所说的内容还不是很清楚。顺便说一句,请考虑删除警告的屏幕截图或将其移至其他问题,因为它与此问题无关,并且会使阅读更加混乱。谢谢
-
@Miguel 明白了,我已经删除了这部分问题,并添加了我自己的答案,因为我就这个问题咨询了 SFML 论坛。 en.sfml-dev.org/forums/index.php?topic=27616.0
标签: c++ visual-studio sfml