diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ea20bd..331de81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,18 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$") # 包含SDL3子项目 add_subdirectory(third_party/SDL3) -# 添加可执行文件 -add_executable(SporeBG-Conid src/main.cpp) +set(SOURCE_FILES + src/main.cpp + src/core/Game.cpp + src/core/Game.h + src/ui/Render.cpp + src/ui/Render.h +) +# 添加可执行文件 +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) + +target_include_directories(SporeBG-Conid PRIVATE ${CMAKE_SOURCE_DIR}/src) # 使用正确的目标名称链接SDL3 # 方法1:使用别名(推荐) target_link_libraries(SporeBG-Conid PRIVATE SDL3::SDL3) diff --git a/README.md b/README.md index 90416c7..9fa8b73 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,41 @@ cd build cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ .. ninja ``` +## 项目结构 +```bash +ChessGame/ +├── src/ +│ ├── core/ # 核心游戏逻辑 +│ │ ├── Game.h/cpp # 游戏主循环和状态管理 +│ │ ├── Board.h/cpp # 棋盘逻辑和规则实现 +│ │ ├── Piece.h/cpp # 棋子基类和具体棋子实现 +│ │ └── Rules.h/cpp # 游戏规则验证 +│ ├── ai/ # 人工智能模块 +│ │ ├── AIBase.h/cpp +│ │ ├── MinimaxAI.h/cpp +│ │ └── Heuristics.h/cpp +│ ├── network/ # 网络模块 +│ │ ├── NetworkManager.h/cpp +│ │ ├── Protocol.h/cpp +│ │ └── Server.h/cpp +│ ├── ui/ # 用户界面 +│ │ ├── Renderer.h/cpp # 渲染器(SDL3) +│ │ ├── UIComponents.h/cpp +│ │ └── MenuSystem.h/cpp +│ ├── input/ # ← 新增:输入处理模块(键盘、鼠标等) +│ │ ├── InputManager.h/cpp +│ ├── utils/ # 工具类 +│ │ ├── Logger.h/cpp +│ │ ├── Config.h/cpp +│ │ └── Utils.h/cpp +│ └── main.cpp # 程序入口(使用 SDL3 回调) +├── assets/ # 资源文件 +│ ├── images/ +│ ├── fonts/ +│ └── sounds/ +├── config/ # 配置文件(如 game.ini) +└── build/ # 构建输出目录(.gitignore 掉) +``` + +## 一些想说的 +这是我第一次用cpp写的项目,想写个比较完整的出来,但是遇到了一堆问题,只能说`路漫漫其修远兮,吾将上下而求索`,如果你有好的建议也是可以提出来的 \ No newline at end of file diff --git a/src/core/Board.cpp b/src/core/Board.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/core/Board.h b/src/core/Board.h new file mode 100644 index 0000000..e69de29 diff --git a/src/core/Game.cpp b/src/core/Game.cpp new file mode 100644 index 0000000..c6387cb --- /dev/null +++ b/src/core/Game.cpp @@ -0,0 +1,40 @@ +// src/core/Game.cpp +#include "Game.h" + + +Game::Game(int g_width, int g_heith) + : Width(g_width), + Height(g_heith), + m_render(std::make_unique()) +{ + +} + + +Game::~Game() { + cleanup(); +} +//清理资源 +void Game::cleanup() { + + +} + + +bool Game::initialize() { + if (!m_render->initialize()) { + return false; + } + + + + + // 初始化游戏特定资源(棋盘、棋子等) + // ... + return true; +} + + +void Game::render() { + m_render->Renderhello(); +} diff --git a/src/core/Game.h b/src/core/Game.h new file mode 100644 index 0000000..093ad73 --- /dev/null +++ b/src/core/Game.h @@ -0,0 +1,24 @@ +// src/core/Game.h +#pragma once +#include +#include +//#include "Board.h" +#include "ui/Render.h" + + + +class Game { +private: + + std::unique_ptr m_render; + int Width; + int Height; + + +public: + Game(int g_width, int g_heith); + ~Game(); + void cleanup(); + bool initialize(); + void render(); +}; \ No newline at end of file diff --git a/src/core/Piece.cpp b/src/core/Piece.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/core/Piece.h b/src/core/Piece.h new file mode 100644 index 0000000..e69de29 diff --git a/src/core/Rule.cpp b/src/core/Rule.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/core/Rule.h b/src/core/Rule.h new file mode 100644 index 0000000..e69de29 diff --git a/src/input/InputManager.cpp b/src/input/InputManager.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/input/InputManager.h b/src/input/InputManager.h new file mode 100644 index 0000000..e69de29 diff --git a/src/main.cpp b/src/main.cpp index 9657d92..6201d70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,67 +1,72 @@ -/* - Copyright (C) 1997-2025 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely. -*/ -#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#define SDL_MAIN_USE_CALLBACKS 1 // 启用回调函数模式 #include #include +#include "core/Game.h" -static SDL_Window *window = NULL; -static SDL_Renderer *renderer = NULL; -/* This function runs once at startup. */ -SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) -{ - /* Create the window */ - if (!SDL_CreateWindowAndRenderer("Hello World", 800, 600, SDL_WINDOW_FULLSCREEN, &window, &renderer)) { - SDL_Log("Couldn't create window and renderer: %s", SDL_GetError()); +//使用SDL3的appstate进行隔离,避免全局变量 +struct AppState { + std::unique_ptr game; +}; + + + +static const int WIDTH = 1600; +static const int HEIGHT = 900; + + +// 1. 应用程序初始化回调 +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) { + // 设置应用元数据[8](@ref) + SDL_SetAppMetadata("孢子棋", "1.0.0", "com.zhenyan121.sporechess"); + + // 初始化SDL视频子系统[6,7](@ref) + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_Log("SDL初始化失败: %s", SDL_GetError()); return SDL_APP_FAILURE; } + // 创建游戏实例 + auto state = new AppState(); + state->game = std::make_unique(WIDTH, HEIGHT); + + + if (!state->game->initialize()) { + SDL_Log("游戏初始化失败!"); + delete state; + return SDL_APP_FAILURE; + } + + return SDL_APP_CONTINUE; } -/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ -SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) -{ +// 2. 事件处理回调 +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { + auto s = static_cast(appstate); if (event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_QUIT) { return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ } + + return SDL_APP_CONTINUE; } -/* This function runs once per frame, and is the heart of the program. */ -SDL_AppResult SDL_AppIterate(void *appstate) -{ - const char *message = "Hello World!"; - int w = 0, h = 0; - float x, y; - const float scale = 4.0f; - - /* Center the message and scale it up */ - SDL_GetRenderOutputSize(renderer, &w, &h); - SDL_SetRenderScale(renderer, scale, scale); - x = ((w / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(message)) / 2; - y = ((h / scale) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2; - - /* Draw the message */ - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); - SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); - SDL_RenderDebugText(renderer, x, y, message); - SDL_RenderPresent(renderer); - +// 3. 主循环迭代回调(每帧调用) +SDL_AppResult SDL_AppIterate(void *appstate) { + auto s = static_cast(appstate); + if (s->game) { //防止空指针 + // 更新游戏逻辑 + + + // 渲染帧 + s->game->render(); + } return SDL_APP_CONTINUE; } -/* This function runs once at shutdown. */ -void SDL_AppQuit(void *appstate, SDL_AppResult result) -{ +// 4. 应用退出回调(清理资源) +void SDL_AppQuit(void *appstate, SDL_AppResult result) { + delete static_cast(appstate); + SDL_Quit(); } \ No newline at end of file diff --git a/src/ui/Render.cpp b/src/ui/Render.cpp new file mode 100644 index 0000000..bb781b8 --- /dev/null +++ b/src/ui/Render.cpp @@ -0,0 +1,53 @@ +#include "Render.h" + +Renderer::Renderer(int WIDTH, int HEIGHT) : Width(WIDTH), Height(HEIGHT) { + +} + +Renderer::Renderer() : Width(1600), Height(900) { + +} + +Renderer::~Renderer() { + if (m_renderer) SDL_DestroyRenderer(m_renderer); + if (m_window) SDL_DestroyWindow(m_window); +} + +bool Renderer::initialize() { + // 创建窗口(支持高DPI和横屏)[3,4](@ref) + m_window = SDL_CreateWindow( + "孢子棋", // 窗口标题,显示在标题栏上 + Width, // 窗口的逻辑宽度(例如 800),用于统一布局,不受屏幕 DPI 影响 + Height, // 窗口的逻辑高度(例如 600) + SDL_WINDOW_HIGH_PIXEL_DENSITY | // 启用高像素密度支持(HiDPI/Retina),确保在高分屏上画面清晰 + SDL_WINDOW_RESIZABLE // 允许用户调整窗口大小(可拉伸) +); + if (!m_window) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "创建窗口失败: %s", SDL_GetError()); + return false; + } + + // 创建渲染器 + m_renderer = SDL_CreateRenderer(m_window, nullptr); //自动选择合适渲染器,开启硬件加速和垂直同步 + if (!m_renderer) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "创建渲染器失败: %s", SDL_GetError()); + return false; + } + + // 设置逻辑呈现模式,实现分辨率自适应[3](@ref) + SDL_SetRenderLogicalPresentation(m_renderer, + Width, + Height, + SDL_LOGICAL_PRESENTATION_LETTERBOX); + SDL_SetWindowSize(m_window, Width, Height); + return true; +} + +void Renderer::Renderhello() { + SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255); + SDL_RenderClear(m_renderer); + SDL_SetRenderDrawColor(m_renderer, 255, 255, 255, 255); + SDL_RenderPresent(m_renderer); +} \ No newline at end of file diff --git a/src/ui/Render.h b/src/ui/Render.h new file mode 100644 index 0000000..4307aee --- /dev/null +++ b/src/ui/Render.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +class Renderer +{ +private: + SDL_Window* m_window = nullptr; + SDL_Renderer* m_renderer = nullptr; + int Width; + int Height; +public: + Renderer(int WIDTH, int HEIGHT); + Renderer(); + ~Renderer(); + bool initialize(); + void Renderhello(); +}; + +