所以我正在尝试使用SFML中的.setFont(sf::Font)
方法,它似乎以某种方式打破了sf::Text
对象的其余部分。我正在使用以下函数执行此操作:
sf::Text Renderer::CreateText(FontEntity font)
{
sf::Text out;
out.setFont(font.GetFont());
out.setString(font.GetText());
out.setCharacterSize(24);
out.setColor(sf::Color::White);
out.setStyle(sf::Text::Bold);
return out;
}
上面用于我已经实现的绘制调用,并且我认为问题可能在哪里(虽然我不确定在哪里):
void Renderer::Draw(DrawData* drawData)
{
this->window->clear();
for (Entity* entity: drawData->GetEntities())
{
auto fontEntity = static_cast<FontEntity*>(entity);
// If font entity
if (fontEntity)
{
sf::Text text = CreateText(*fontEntity);
this->window->draw(text);
}
}
this->window->display();
}
循环遍历Entity
个对象列表,将它们转换为FontEntity
个对象,将转换后的FontEntity
传递给CreateText(FontEntity)
方法,然后尝试绘制{ {1}}返回。
然而,当调用sf::Text
时,我得到例外:
0x6177BA8C(sfml-graphics-d-2.dll)中的未处理异常 GameEngine.exe:0xC0000005:访问冲突读取位置 0x0000000D。
另一方面,如果删除out.setString(font.GetText());
行,则不会发生此错误。
我想知道是否有人确切知道这里发生了什么?我似乎无法就这个具体问题找到任何建议,我已经尝试(并且失败)关注SFML Text and fonts tutorial。
我的第一个想法是,我有一些狡猾的指针问题正在进行,但据我理解教程,我正在尝试做的应该没问题。
out.setFont(font.GetFont())
类是一个自定义类,我用它来管理有效的可绘制字符串,但可以很好地存储在我的FontEntity
对象列表中。
.h文件,如果有帮助,如下:
Entity
.cpp文件:
#include "Entity.h"
#include <string>
#include "SFML\Graphics.hpp"
class FontEntity : public Entity
{
public:
FontEntity(float x, float y, sf::Font font);
FontEntity(float x, float y, sf::Font font, std::string text);
~FontEntity(void);
std::string GetText(void);
void SetText(std::string);
sf::Font GetFont(void);
void SetFont(sf::Font);
int GetSize(void);
void SetSize(int);
protected:
std::string text;
sf::Font font;
int size;
};
感谢阅读!所有输入都完全受到赞赏。
答案 0 :(得分:1)
sf::Font
是重物,永远不会按值传递它们,总是像参考一样:
class FontEntity : public Entity
{
public:
FontEntity(float x, float y, sf::Font* font);
FontEntity(float x, float y, sf::Font* font, std::string text);
~FontEntity(void);
// every member function that do not modify the object
// should be const.
std::string GetText(void) const;
// most of the time, it's more efficient to pass-by-reference
// except for base type (int, char, etc.)
// std::string are not that big, so it's not really inefficient to
// pass them by value
void SetText(const std::string&);
// you don't want the rest of the code messing with the font
// parameter since it will affect every object that is using it.
const sf::Font *GetFont(void) const;
void SetFont(sf::Font*);
int GetSize(void) const;
void SetSize(int);
protected:
std::string text;
sf::Font* font; // keep a pointer to the sf::font
int size;
};
另一方面,sf::Text
是非常轻量级的对象,旨在被复制并传递到任何地方。
正如@ Pawnguy7评论的那样,错误来自于您通过值传递sf::Font
。这与您使用C ++的方式有关,而与SFML的工作方式无关。有关在C ++中传递对象的信息,请参阅Rules of thumb。
另一件事是,我真的不明白为什么你有FontEntity
。你应该只保留sf :: Text的向量或列表(你喜欢的任何容器),然后只需通过那个向量并调用this->window->draw(yourTextContainer.at(i));
或类似的东西。
如果sf :: Font是汽车杂志和sf :: Text汽车轮胎,那么你的FontEntity就像是试图将轮胎放在轮胎上的轮胎上。
另外,为什么要将FontEntity对象保存在Entity容器中?铸造是一项昂贵的操作,如果可能的话,应该不惜一切代价避免设计。另一个昂贵的操作是为每个框架创建每个FontEntity的文本,你应该做的是创建它们一次并在渲染后存储它们。