2013-10-24 93 views
1

所以我試圖使用SFML中的.setFont(sf::Font)方法,它似乎以某種方式破壞了sf::Text對象的其餘部分。我使用下面的函數來做到這一點:SFML 2.1「setFont」未處理的異常

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目的,經過轉換FontEntityCreateText(FontEntity)方法,然後試圖繪製返回的sf::Text

然而,當out.setString(font.GetText());被調用時,我得到異常:

在0x6177BA8C(SFML圖形-d-2.DLL)在 GameEngine.exe未處理的異常:0000005:訪問衝突讀取位置 0x0000000D。

另一方面,如果我刪除out.setFont(font.GetFont())行,則不會發生此錯誤。

我想知道是否有人知道這裏發生了什麼?我似乎無法在這個特定問題上找到任何建議,並且我試過(並且失敗)遵循SFML Text and fonts tutorial

我的第一個想法是,我有一些可怕的指針問題正在進行,但據我瞭解教程,我試圖做的應該沒問題。

FontEntity類是我用來管理什麼是有效可繪製字符串的自定義類,但可以很好地存儲在我的Entity對象列表中。

.h文件,如果有幫助,如下:

#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; 
}; 

和.cpp文件:

#include "stdafx.h" 
#include "FontEntity.h" 


FontEntity::FontEntity(float x, float y, sf::Font font) : Entity(x, y) 
{ 
    this->text = ""; 
    this->font = font; 
} 

FontEntity::FontEntity(float x, float y, sf::Font font, std::string text) : Entity(x, y) 
{ 
    this->text = text; 
    this->font = font; 
} 

FontEntity::~FontEntity(void) 
{ 
} 

std::string FontEntity::GetText(void) 
{ 
    return this->text; 
} 

void FontEntity::SetText(std::string text) 
{ 
    this->text = text; 
} 

sf::Font FontEntity::GetFont(void) 
{ 
    return this->font; 
} 

void FontEntity::SetFont(sf::Font font) 
{ 
    this->font = font; 
} 

int FontEntity::GetSize(void) 
{ 
    return this->size; 
} 

void FontEntity::SetSize(int size) 
{ 
    this->size = size; 
} 

感謝您的閱讀!所有的輸入是完全讚賞。

+2

sf :: Text保存對其使用的sf :: Font的引用。由於這個原因,你不應該把它設置爲臨時的。看來你在這裏做(getFont()返回值,而不是引用)。因此,字體超出了範圍並死亡,但它仍然指向它。我不是積極的,這是問題,但我會檢查它。 – 2013-10-24 02:53:21

回答

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是非常輕對象,並被設計爲複製並傳遞到處。

As @ Pawnguy7評論道,錯誤來自您傳遞sf::Font的值。這與你如何使用C++而不是SFML如何工作有關。有關在C++中傳遞對象的信息,請參見Rules of thumb。現在

您FontEntity

另一件事是,我真的不明白,爲什麼你有FontEntity。你應該只保留一個向量或列表(你喜歡的任何容器)的sf :: Text,然後通過該向量並調用this->window->draw(yourTextContainer.at(i));或類似的東西。

如果SF ::字體是汽車彈匣和SF ::文本汽車輪胎,你FontEntity會像試圖把一個輪胎在輪胎上的車輪。

另外,爲什麼讓你的FontEntity對象的實體容器?鑄造是一項昂貴的操作,如果可能的話,應儘可能避免設計。什麼是另一個昂貴的操作是爲每個FontEntity的每一幀創建文本,你應該做的就是創建一次並將它們存儲在渲染之後。