【问题标题】:I can't load my game resources into SFML with CMake我无法使用 CMake 将我的游戏资源加载到 SFML
【发布时间】:2022-01-25 04:47:41
【问题描述】:

我正在用 C++ 编写一个小游戏,使用 Visual Studio Code 和 CMake 作为构建系统。到目前为止,访问资源没有任何问题,但由于我决定通过在目录中组织项目来整理项目,因此我的 GetTexture、GetSoundBuffer 和 GetFont 函数无法从 Resources 文件夹加载图像。

显然我知道将文件保存在不同的目录中时,我必须更新路径。所以一开始是“Resources / image.png”变成了“../../../Resources/image.png”,(这对所有#include指令都有效)但是当我运行游戏时,我只看到黑屏和控制台向我显示无法加载图像“../../../Resources/image.png”之类的消息。原因:无法打开文件

我一遍又一遍地尝试重新安排项目,但每次编译都会发生这种情况。我对 CMake 了解不多,我不知道问题出在我的 CMakeLists.txt 文件还是我之前提到的函数上,我怀疑它们之前工作得很好。

获取纹理:

sf::Texture& Game::GetTexture(std::string _fileName)
{
    auto iter = textures.find(_fileName);

    if (iter != textures.end())
    {
        return *iter->second;
    }

    TexturePtr texture = std::make_shared<sf::Texture>();

    texture->loadFromFile(_fileName);

    textures[_fileName] = texture;

    return *texture;
}

获取声音缓冲区:

sf::SoundBuffer& Game::GetSoundBuffer(std::string _fileName)
{
    auto iter = sounds.find(_fileName);

    if (iter != sounds.end())
    {
        return *iter->second;
    }

    SoundBufferPtr sound = std::make_shared<sf::SoundBuffer>();

    sound->loadFromFile(_fileName);

    sounds[_fileName] = sound;

    return *sound;
}

获取字体:

sf::Font& Game::GetFont(std::string _fileName)
{
    auto iter = fonts.find(_fileName);

    if (iter != fonts.end())
    {
        return *iter->second;
    }

    FontPtr font = std::make_shared<sf::Font>();

    font->loadFromFile(_fileName);

    fonts[_fileName] = font;

    return *font;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.18)
set(PROJECT_NAME "MyGame")
project(MyGame)

set(SFML_DIR "${CMAKE_CURRENT_LIST_DIR}/libs/SFML-2.5.1/lib/cmake/SFML")

file(GLOB ALL_REQUIRED_DLL "libs/required_dlls/*.dll")
file(COPY ${ALL_REQUIRED_DLL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

set(CMAKE_CXX_STANDARD 17)

set(SOURCE_FILES
    ...
  ${RES_FILES})
  

add_executable(${PROJECT_NAME} ${SOURCE_FILES})

find_package(SFML 2.5.1 COMPONENTS system window graphics network audio REQUIRED)
target_link_libraries(${PROJECT_NAME} sfml-audio sfml-graphics sfml-window sfml-system)

项目组织如下:

Build:
     (Cmake build stuff)

Engine:
     (All engine codes, no problem here)

Scenes:
     Scene1:
         include:
             (All .h files)
         src:
             (All .cpp files, here is where i call GetTexture, GetSoundBuffer
              and GetFont)

Resources:
     (All the images, sounds and fonts)

CMakeLists.txt
main.cpp 

对于这一切,还值得一提的是我使用的是 Linux。

【问题讨论】:

    标签: c++ cmake path game-engine sfml


    【解决方案1】:

    当您在另一个位置运行可执行文件时,相对路径将与编译期间不同。

    一种解决方案是使所有内容都与可执行文件的位置相关,如下所示:

    namespace fs = std::filesystem;
    int main( int argc, char* argv[] ) {
        fs::path path( fs::canonical( argv[0] ) );
        fs::path file = path.parent_path() / "sound.wav";
        std::cout << file << std::endl;
    }
    

    结果:

    Program stdout
    "/app/sound.wav"
    

    代码:https://godbolt.org/z/K7PPchdjT

    另一种解决方案是将文件合并到实际的可执行文件中。我在这里回答了类似的问题:

    how to put files and exported functions in one dll?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 2021-09-21
      • 2022-12-31
      • 1970-01-01
      相关资源
      最近更新 更多