使用Imgui和SDL2做的一个弹球小游戏-Bounze
使用Imgui和SDL2做的一个弹球小游戏-Bounze
油管上面TheCherno博主分享的一个视频FIRST GAME in C++! Did He Do a Good Job? // Code Review (C++/SDL2)里面分享了一个Github项目:
https://github.com/staticaron/Bounze
使用了Imgui和SDL2,并且可以设置音乐播放,修改音量等,玩家可以得分等,目前游戏支持Windows和Linux,稍微改一下代码还可以支持MacOS,最终支持Windows、Linux、MacOS的源码版本我已经上传至我的github上,源代码链接地址为:https://github.com/ccf19881030/Bounze,欢迎下载体验学习。
修改代码已支持MacOS
- 1、处理编译告警错误
-Wc++11-narrowing warning
我的MacOS(Mac Mini4)实际编译过程中遇到如下的类型转换错误:
make之后报错如下:-Wc++11-narrowing 需要在CMakeLists.txt文件中添加预处理定义避免次错误,如下所示:
In file included from /Users/john/WorkSpace/CppProjects/Bounze/src/Ball.cpp:10:/Users/john/WorkSpace/CppProjects/Bounze/include/managers/config.h:4:10: warning: non-portable path to file \'\"mini/ini.h\"\'; specified path differs in case from file name on disk [-Wnonportable-include-path] 4 | #include \"mIni/ini.h\" | ^~~~~~~~~~~~ | \"mini/ini.h\"1 warning generated.[ 91%] Building CXX object CMakeFiles/bounze.dir/src/Bat.cpp.oIn file included from /Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:7:/Users/john/WorkSpace/CppProjects/Bounze/include/managers/config.h:4:10: warning: non-portable path to file \'\"mini/ini.h\"\'; specified path differs in case from file name on disk [-Wnonportable-include-path] 4 | #include \"mIni/ini.h\" | ^~~~~~~~~~~~ | \"mini/ini.h\"/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:20: error: type \'float\' cannot be narrowed to \'int\' in initializer list [-Wc++11-narrowing] 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:20: note: insert an explicit cast to silence this issue 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | static_cast( )/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:73: error: type \'float\' cannot be narrowed to \'int\' in initializer list [-Wc++11-narrowing] 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:73: note: insert an explicit cast to silence this issue 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | static_cast( )/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:126: error: type \'float\' cannot be narrowed to \'int\' in initializer list [-Wc++11-narrowing] 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:126: note: insert an explicit cast to silence this issue 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~ | static_cast( )/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:151: error: type \'float\' cannot be narrowed to \'int\' in initializer list [-Wc++11-narrowing] 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~/Users/john/WorkSpace/CppProjects/Bounze/src/Bat.cpp:37:151: note: insert an explicit cast to silence this issue 37 | SDL_Rect rect = { GetCenter().x - GetBoundDetails().GetHalfBounds().x, GetCenter().y - GetBoundDetails().GetHalfBounds().y, m_EntityBounds.bounds.x, m_EntityBounds.bounds.y }; | ^~~~~~~~~~~~~~~~~~~~~~~ | static_cast( )1 warning and 4 errors generated.make[2]: *** [CMakeFiles/bounze.dir/src/Bat.cpp.o] Error 1make[1]: *** [CMakeFiles/bounze.dir/all] Error 2make: *** [all] Error 2
-Wc++11-narrowing
是一个编译器警告,通常与 C++11 标准中对窄化转换(narrowing conversion)的限制有关。如果你想通过在 CMakeLists.txt 文件中添加预处理定义来避免此错误,可以使用以下方法:
修改 CMakeLists.txt
在你的 CMakeLists.txt 文件中,添加以下行以禁用该警告:
# Suppress the -Wc++11-narrowing warning based on platformif (APPLE) target_compile_options(\"${PROJECT_NAME}\" PRIVATE -Wno-c++11-narrowing)elseif (UNIX AND NOT APPLE) # Linux target_compile_options(\"${PROJECT_NAME}\" PRIVATE -Wno-c++11-narrowing)elseif (WIN32) # Windows target_compile_options(\"${PROJECT_NAME}\" PRIVATE /wd4267 /wd4996)endif()
修改后的完整CMakeLists.txt
文件内容如下:
cmake_minimum_required(VERSION \"3.19.2\")set(CMAKE_MSVC_RUNTIME_LIBRARY \"MultiThreaded$<$:Debug>\")project(\"bounze\")option(BUILD_SHARED_LIBS \"\" OFF)set(SDL2IMAGE_VENDORED ON CACHE BOOL \"\" FORCE)set(SDL2IMAGE_PNG ON CACHE BOOL \"\" FORCE)set(SDL2IMAGE_AVIF OFF CACHE BOOL \"\" FORCE)set(SDL2IMAGE_JPG OFF CACHE BOOL \"\" FORCE)set(SDL2IMAGE_TIF OFF CACHE BOOL \"\" FORCE)set(SDL2IMAGE_WEBP OFF CACHE BOOL \"\" FORCE)set(SDL2IMAGE_STB OFF CACHE BOOL \"\" FORCE)set(SDL2TTF_VENDORED ON CACHE BOOL \"\" FORCE)set(SDL2MIXER_FLAC OFF CACHE BOOL \"\" FORCE)set(SDL2MIXER_MP3 OFF CACHE BOOL \"\" FORCE)set(SDL2MIXER_MOD OFF CACHE BOOL \"\" FORCE)set(SDL2MIXER_OPUS OFF CACHE BOOL \"\" FORCE)set(SDL2MIXER_MIDI OFF CACHE BOOL \"\" FORCE)set(SDL2MIXER_INSTALL OFF CACHE BOOL \"\" FORCE)add_subdirectory(vendor/SDL)add_subdirectory(vendor/SDL_image)add_subdirectory(vendor/SDL_ttf)add_subdirectory(vendor/SDL_mixer)add_subdirectory(vendor/imgui)add_subdirectory(vendor/glm)add_subdirectory(vendor/mIni)set(CMAKE_CXX_STANDARD 20)file(GLOB_RECURSE MY_SOURCES CONFIGURE_DEPENDS \"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp\")add_executable(\"${PROJECT_NAME}\" \"${MY_SOURCES}\")# target_compile_definitions(\"${PROJECT_NAME}\" PUBLIC RESOURCE_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}/resources/\")target_compile_definitions(\"${PROJECT_NAME}\" PUBLIC RESOURCE_PATH=\"./resources/\")target_compile_definitions(\"${PROJECT_NAME}\" PRIVATE SDL_MAIN_HANDLED)# Suppress the -Wc++11-narrowing warning based on platformif (APPLE) target_compile_options(\"${PROJECT_NAME}\" PRIVATE -Wno-c++11-narrowing)elseif (UNIX AND NOT APPLE) # Linux target_compile_options(\"${PROJECT_NAME}\" PRIVATE -Wno-c++11-narrowing)elseif (WIN32) # Windows target_compile_options(\"${PROJECT_NAME}\" PRIVATE /wd4267 /wd4996)endif()target_include_directories(\"${PROJECT_NAME}\" PUBLIC \"${CMAKE_CURRENT_SOURCE_DIR}/include\")target_include_directories(\"${PROJECT_NAME}\" PUBLIC \"${CMAKE_CURRENT_SOURCE_DIR}/vendor/SDL_mixer/include\")target_include_directories(\"${PROJECT_NAME}\" PUBLIC \"${CMAKE_CURRENT_SOURCE_DIR}/vendor/SDL_ttf\")target_include_directories(\"${PROJECT_NAME}\" PUBLIC \"${CMAKE_CURRENT_SOURCE_DIR}/vendor/SDL_image/include\")target_link_libraries(\"${PROJECT_NAME}\" PRIVATE SDL2::SDL2-static SDL2_image::SDL2_image-static SDL2_ttf::SDL2_ttf-static SDL2_mixer::SDL2_mixer-static imgui mINI glm)
- 2、需要注释掉源代码
Bounze/src/levels/About.cpp
中的一行代码#error \"Unsupported OS\"
,如下所示:
void openUrlAllPlatforms( std::string url ){#ifdef _WIN32std::string command = \"start \";command += url;system( command.c_str() );#elif __linux__std::string command = \"xdg-open \";command += url;system( command.c_str() );#else// #error \"Unsupported OS\"#endif}}
或者更近一步修改成如下的代码已支持About
菜单项在MacOS
中打开代码和音乐等资源网址:
void openUrlAllPlatforms( std::string url ){#ifdef _WIN32std::string command = \"start \";command += url;system( command.c_str() );#elif __linux__std::string command = \"xdg-open \";command += url;system( command.c_str() );#else#ifdef __APPLE__#include #if TARGET_OS_MAC // macOS-specific code std::string command = \"open \"; command += url; system( command.c_str() );#endif#endif#endif}
不然会报如下的错误:
/Users/john/WorkSpace/CppProjects/Bounze/include/levels/ILevel.h:18:15: note: overridden virtual function is here 18 | virtual void Unload() = 0; |^4 warnings generated.[ 92%] Building CXX object CMakeFiles/bounze.dir/src/levels/About.cpp.oIn file included from /Users/john/WorkSpace/CppProjects/Bounze/src/levels/About.cpp:9:/Users/john/WorkSpace/CppProjects/Bounze/include/managers/config.h:4:10: warning: non-portable path to file \'\"mini/ini.h\"\'; specified path differs in case from file name on disk [-Wnonportable-include-path] 4 | #include \"mIni/ini.h\" | ^~~~~~~~~~~~ | \"mini/ini.h\"/Users/john/WorkSpace/CppProjects/Bounze/src/levels/About.cpp:59:2: error: \"Unsupported OS\" 59 | #error \"Unsupported OS\" | ^1 warning and 1 error generated.make[2]: *** [CMakeFiles/bounze.dir/src/levels/About.cpp.o] Error 1make[1]: *** [CMakeFiles/bounze.dir/all] Error 2make: *** [all] Error 2
发现现在的AI对于写代码还有解决错误实在是太友好了,比如在VSCode
中集成Github Copilot
或者CodeMate
能省事不少,比如说编译报错,代码格式化,CMake编译问题、C++问题等等。
紧接着MacOS和Linux编译运行的流程一样:
- Create a folder
/build
- Enter the folder
cd build
- Run the cmake command
cmake ..
- Make the build file
make
编译完成生成bounze
二进制文件之后,需要将资源文件夹resources
和二进制文件bounze
放在同一目录下,不然直接运行bounze
二进制文件,会报如下错误:
在我的Mac Mini4中的运行截图如下所示:
Bounze
游戏
How to Play.
- The ball bounces off the bat randomly in normal mode.
- If boost is active, the ball bounces off according to where it collides with the bat.
- Balancing the ball on bat and destroying the diamonds using the boosted ball gives points.
- Get the highscore.
- I left the debug imgui in the game where you can modify the volumes etc. Press
TAB
to access.
How to build.
Windows + Visual Studio
- Open the folder in visual studio as Cmake Project.
Ctrl + S
on the CMakeLists.txt file to build the project.- Run
bounze.exe
.
NOTE : Copy the /resources
folder in same directory as the .exe
file.
LINUX
- Create a folder
/build
- Enter the folder
cd build
- Run the cmake command
cmake ..
- Make the build file
make
macOS
- Create a folder
/build
- Enter the folder
cd build
- Run the cmake command
cmake ..
- Make the build file
make
NOTE : Copy the /resources
folder in same directory as the .exe
file.
参考上述https://github.com/staticaron/Bounze的README.md
文件,下载上述项目后,在Window11中使用VS2022打开下载的目录,以CMake工程打开;
接着打开CMakeLists.txt
,执行Ctrl+S
编译,生成Makefile等工程文件;最后将代码根目录下的resources
资源文件夹拷贝到和bounze.exe
同级目录,运行bounze.exe
可执行程序
然后鼠标双击bounze.exe
可执行程序,
如果不拷贝resources
资源文件夹,直接鼠标双击bounze.exe
可执行程序,会报如下的错误:
ERROR loading the font at : ./resources/fonts/mightysouly.ttf Couldn\'t open ./resources/fonts/mightysouly.ttf
加载资源文件报错,因为找不到资源文件所在目录。