我知道这个主题在论坛中很丰富,但我需要帮助解决这个问题。我正在关注this tutorial为一个tic tac toe游戏制作一个基本的sfml ImageManager类。我在理解如何在我的游戏引擎中实现这个类时遇到了麻烦。我将发布大量代码,因为涉及多个类: Board.h:我的tic-tac-toe游戏板。
#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 :(得分:0)
我认为textures_
是ImageManager
类的私有成员?在这种情况下,您有undefined behavior,因为ImageManager::GetImage
会将引用返回到存储在已销毁的容器中的数据(请记住imgr
是构造函数中的局部变量)。
答案 1 :(得分:0)
好的,我有。这是一个非常令人尴尬的解决方案,但在ImageManager imgr
的构造函数中声明我的Board
正在立即销毁我的ImageManager,所以我只剪切该实例并将其粘贴到头文件中。由于某些原因,返回引用而不是实际的纹理值是必要的,这也让我感到难过。