游戏开发学习-01-搭建项目
最近想学游戏开发... 说起来很早以前就想做游戏的, 但是误入歧途了(也许吧). 最近利用空余时间尝试写一下游戏, 目标是先做一个 demo, 熟悉之后再设计一个自己的游戏
技术栈与工具链
此前没有接触过游戏开发, 只在大学的时候学过一点点 OpenGL. 我打算从较为原始的方式开始, 先不用游戏引擎, 由于我本身不会 C++, 用 C# 的话不如直接上 Unity, 于是便选择了 C + raylib 来写
raylib 对应的还有一个库叫 raygui, 这是一个 UI 库, 我打算用这个库来画按钮等
构建工具我打算选择 CMake + Make, 并且不需要包管理器, 手动管理依赖
由于我在 macOS 上开发, 编译器的话自然就选择 clang 了, 版本为 21.1.8 (macOS 上自带的版本为 17.0.0)
工具链: clang (21.1.8), CMake (4.2.2), Make (4.4.1)
技术栈: C (23), raylib (latest), raygui (latest)
编辑工具: nvim
raylib 安装:
brew install raylib
raygui 下载: https://github.com/raysan5/raygui, 直接下载头文件即可
项目结构
我打算将游戏逻辑和渲染层分开
core: 游戏核心逻辑
client: 游戏渲染
lib: 通用库
third_party: 第三方依赖
build: 构建产物
然后头文件都放在各个模块的 include 文件夹下, 源码放在 src 文件夹下
项目结构就是这样:
game_project
├─build
├─client
| ├─include
| └─src
├─core
| ├─include
| └─src
├─lib
| └─lib_1
| ├─include
| └─src
└─third_party
└─raygui
依赖关系:
┌───── lib
| ↗ ↖
| core ← client
| ↓ ↙
└→ third_party
core 作为一个库给 client 使用
项目初始化
项目的根目录放一个 CMakeLists.txt, 在每个子模块下面也放一个 CMakeLists.txt, 并在顶层将模块包含进去
game_project
├─client
| ├─include
| ├─src
| └─CMakeLists.txt
├─core
| ├─include
| ├─src
| └─CMakeLists.txt
├─lib
| ├─lib_1
| | ├─include
| | ├─src
| | └─CMakeLists.txt
| └─CMakeLists.txt
├─third_party
└─CMakeLists.txt
game_project/CMakeLists.txt:
cmake_minimum_required(VERSION 3.30)
project(game_project C)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
if(MSVC)
add_compile_options(/W4)
else()
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
add_subdirectory(core)
add_subdirectory(client)
add_subdirectory(lib)
game_project/client/CMakeLists.txt:
set(RAYLIB_VERSION 5.5)
find_package(raylib ${RAYLIB_VERSION} REQUIRED)
if(NOT raylib_FOUND)
include(FetchContent)
FetchContent_Declare(
raylib
DOWNLOAD_EXTRACT_TIMESTAMP OFF
URL https://github.com/raysan5/raylib/archive/refs/tags/${RAYLIB_VERSION}.tar.gz
)
FetchContent_GetProperties(raylib)
if(NOT raylib_POPULATED)
set(FETCHCONTENT_QUIET NO)
FetchContent_MakeAvailable(raylib)
endif()
endif()
file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c")
add_executable(client ${SOURCES})
target_include_directories(
client
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${PROJECT_SOURCE_DIR}/third_party/stb/include
PRIVATE ${PROJECT_SOURCE_DIR}/third_party/raygui/include)
if(APPLE)
target_link_libraries(client PRIVATE "-framework IOKit" "-framework Cocoa"
"-framework OpenGL")
elseif(UNIX AND NOT APPLE)
target_link_libraries(client PRIVATE m)
endif()
target_link_libraries(client PRIVATE raylib xlog core)
target_compile_options(client PRIVATE $<$<CONFIG:Release>:-O3 -DNDEBUG>)
game_project/core/CMakeLists.txt:
file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c")
file(GLOB_RECURSE TEST_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/test/*.c")
add_executable(core_main ${SOURCES} ${TEST_SOURCES})
add_library(core ${SOURCES})
target_include_directories(
core
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${PROJECT_SOURCE_DIR}/third_party/stb/include)
target_include_directories(
core_main
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${PROJECT_SOURCE_DIR}/third_party/stb/include)
Makefile:
BUILD_DIR := build
DEBUG_DIR := $(BUILD_DIR)/debug
RELEASE_DIR := $(BUILD_DIR)/release
CC ?= clang
CMAKE := cmake
CMAKE_PRESET ?= ninja
CMAKE_FLAGS ?= -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
ifneq ($(CC),)
CMAKE_FLAGS += -DCMAKE_C_COMPILER=$(CC)
endif
all: debug
debug: CMakeLists.txt
$(CMAKE) --preset=$(CMAKE_PRESET) -S . -B $(DEBUG_DIR) \
$(CMAKE_FLAGS) -DCMAKE_BUILD_TYPE=Debug
$(CMAKE) --build $(DEBUG_DIR)
cp $(DEBUG_DIR)/compile_commands.json compile_commands.json
release: CMakeLists.txt
$(CMAKE) --preset=$(CMAKE_PRESET) -S . -B $(RELEASE_DIR) \
$(CMAKE_FLAGS) -DCMAKE_BUILD_TYPE=Release
$(CMAKE) --build $(RELEASE_DIR)
clean:
rm -rf $(BUILD_DIR)
.PHONY: all debug release clean
CMakePresets.json:
{
"version": 8,
"configurePresets": [
{
"name": "ninja",
"generator": "Ninja",
"displayName": "Default Ninja Config",
"description": "Using generator: Ninja"
},
{
"name": "make",
"generator": "Unix Makefiles",
"displayName": "Default Make Config",
"description": "Using generator: Make"
},
{
"name": "xcode",
"generator": "Xcode",
"displayName": "Default Xcode Config",
"description": "Using generator: Xcode"
}
]
}
暂时就这么写吧, 也许得找一个现成的项目学一下
Comments