2014-09-02 42 views
0

我知道這個主題在論壇中很豐富,但我需要幫助解決這個特定的問題。我正在關注this tutorial,爲tic tac toe遊戲製作一個基本的sfml ImageManager類。我無法理解如何在我的遊戲引擎中實現這個類。我會發布很多代碼,因爲涉及多個類: Board.h:我的井字遊戲板。我的sfml ImageManager類僅在C++中顯示白色方塊

#pragma once 
#include "stdafx.h" 
#include <vector> 
#include "Box.h" 
#include "SFML/Graphics.hpp" 
#include "ImageManager.h" 

class Board{ 
public: 
Board(); 
~Board(); 

std::vector<Box> &GetBoxes(); 

sf::Sprite GetGameBoard(); 
private: 
sf::Sprite gameBoard; 

std::vector<Box> boxes; 
}; 

而這裏的Board.cpp:

#include "stdafx.h" 
#include "Board.h" 
#include "SFML/Graphics.hpp" 

Board::Board(){ 
ImageManager imgr; 
imgr.AddResourceDirectory("images/"); 
gameBoard.setTexture(imgr.GetImage("images/t3board.png")); 
} 

Board::~Board(){ 

} 

std::vector<Box> &Board::GetBoxes(){ 
return boxes; 
} 

sf::Sprite Board::GetGameBoard(){ 
return gameBoard; 
} 

這裏是是從教程的ImageManager類相關:

const sf::Texture &ImageManager::GetImage(const std::string &filename){ 
    for(std::map<std::string, sf::Texture>::const_iterator it = textures_.begin(); it != textures_.end(); ++it){ 
     if(filename == it->first){ 
      std::cout << "DEBUG_MESSAGE: " << filename << " using existing image.\n"; 
      return it->second; 
     } 
    } 

    //if image doesn't exist (no need for else since it will return if filename is found 
    sf::Texture texture; 
    if(texture.loadFromFile(filename)){ 
     //create both a string and matching image in the map 
     textures_[filename] = texture; 
     std::cout << "DEBUG_MESSAGE: " << filename << " loading image.\n"; 
     return textures_[filename]; 
    } 

    // If the image has still not been found, search all registered directories 
    //of course, it will be empty until I specify extra directories by adding them into the vector 
    for(std::vector<std::string>::iterator it = resourceDirectories_.begin(); it != resourceDirectories_.end(); ++it){ 
     if(texture.loadFromFile((*it) + filename)){ 
      textures_[filename] = texture; 
      std::cout << "DEBUG_MESSAGE: " << filename << " loading image 2.\n"; 
      return textures_[filename]; 
     } 
    } 

    //again, notice there's no elses because returns serve as breaks 
    std::cout << "GAME_ERROR: Image was not found. It is filled with an empty image.\n"; 
    textures_[filename] = texture; 
    return textures_[filename]; 
} 

最後,在我的引擎,我得到gameBoard和借鑑它到我的窗口:

void Engine::Render(){ 
    window.clear(); 
    window.draw(board.GetGameBoard()); 
    window.display(); 
} 

我的窗口只顯示一個完整的白色背景,但它仍然是功能,否則。任何人都可以看到我做錯了什麼嗎?

+0

http://stackoverflow.com/a/19434823/520217 – Hiura 2014-09-02 15:42:35

+0

謝謝,我明白這個問題,但我不明白這個問題。我需要在哪裏設置紋理的圖像,使其不會丟失? – jburn7 2014-09-02 21:36:25

回答

0

我假設textures_ImageManager類的私人成員?在這種情況下,你有undefined behavior,因爲ImageManager::GetImage返回一個參考到存儲在被銷燬的容器中的數據(記住imgr是構造函數中的局部變量)。

+0

確實:'private:std :: map textures_;'。所以'const sf :: Texture&GetImage(const std :: string&filename);'只是const const sf :: Texture GetImage(const std :: string&filename);'而不是?編輯:單獨不能解決問題。還有什麼需要改變的? – jburn7 2014-09-02 15:13:01

+0

@ jburn7我對SFML沒有太多經驗(特別是他們的'Sprint'類),但它似乎是一個可能的罪魁禍首。如果是這樣,那麼通過價值回報就可以解決問題。 – 2014-09-02 15:15:20

+0

好的,你怎麼知道你的'std :: map'是?這可能是問題:'sf ::紋理紋理; if(texture.loadFromFile(filename))//在地圖中創建一個字符串和一個匹配的圖像012ures_loadFromFile(filename)textures_ [filename] = texture; std :: cout <<「DEBUG_MESSAGE:」<< filename <<「loading image。\ n」; return textures [[文件名];}'(抱歉亂七八糟)因爲我可以告訴,這實際上是返回一個字符串作爲'sf :: Texture'。我的編譯器能不能告訴我這個? – jburn7 2014-09-02 15:22:46

0

好的,我擁有它。這是一個非常尷尬的解決方案,但在Board的構造函數中聲明我的ImageManager imgr正在銷燬我的ImageManager,因此我只是剪切該實例並將其粘貼到頭文件中。由於某種原因,返回一個參考而不是實際的紋理值是必要的,這也難倒了我。