From 3bef8e84ba5e168f48b5b68c0504cf326da030b8 Mon Sep 17 00:00:00 2001 From: Ziyu Date: Thu, 15 May 2025 20:33:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=AA=97=E5=8F=A3=E5=88=9B?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 5 +- assets/json_example.json | 39 ---------- assets/save_json.json | 46 ----------- main.cpp | 143 ----------------------------------- src/engine/core/game_app.cpp | 86 +++++++++++++++++++++ src/engine/core/game_app.h | 42 ++++++++++ src/main.cpp | 7 ++ 7 files changed, 139 insertions(+), 229 deletions(-) delete mode 100644 assets/json_example.json delete mode 100644 assets/save_json.json delete mode 100644 main.cpp create mode 100644 src/engine/core/game_app.cpp create mode 100644 src/engine/core/game_app.h create mode 100644 src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ea527..cf51b35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,10 @@ find_package(nlohmann_json REQUIRED) find_package(spdlog REQUIRED) # 添加可执行文件 -add_executable(${TARGET} main.cpp) +add_executable(${TARGET} + src/main.cpp + src/engine/core/game_app.cpp + ) # 链接库 target_link_libraries(${TARGET} diff --git a/assets/json_example.json b/assets/json_example.json deleted file mode 100644 index 75a52b8..0000000 --- a/assets/json_example.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "张三 (Zhang San)", - "age": 30, - "height_meters": 1.75, - "isStudent": false, - "email": "zhangsan@example.com", - "middleName": null, - "address": { - "street": "人民路123号 (Renmin Road No. 123)", - "city": "示例市 (Sample City)", - "zipCode": "100000", - "isPrimary": true - }, - "hobbies": [ - "编程 (Programming)", - "阅读 (Reading)", - "旅行 (Traveling)" - ], - "scores": [95, 88, 72.5], - "projects": [ - { - "projectName": "项目Alpha (Project Alpha)", - "status": "已完成 (Completed)", - "budget": 50000.75, - "isActive": true - }, - { - "projectName": "项目Beta (Project Beta)", - "status": "进行中 (In Progress)", - "budget": 120000, - "isActive": true, - "deadline": null - } - ], - "metadata": { - "version": 1.2, - "tags": ["data", "example"] - } - } \ No newline at end of file diff --git a/assets/save_json.json b/assets/save_json.json deleted file mode 100644 index 9119888..0000000 --- a/assets/save_json.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "张三 (Zhang San)", - "age": 30, - "height_meters": 1.75, - "isStudent": false, - "email": "zhangsan@example.com", - "middleName": null, - "address": { - "street": "人民路123号 (Renmin Road No. 123)", - "city": "示例市 (Sample City)", - "zipCode": "100000", - "isPrimary": true - }, - "hobbies": [ - "编程 (Programming)", - "阅读 (Reading)", - "旅行 (Traveling)" - ], - "scores": [ - 95, - 88, - 72.5 - ], - "projects": [ - { - "projectName": "项目Alpha (Project Alpha)", - "status": "已完成 (Completed)", - "budget": 50000.75, - "isActive": true - }, - { - "projectName": "项目Beta (Project Beta)", - "status": "进行中 (In Progress)", - "budget": 120000, - "isActive": true, - "deadline": null - } - ], - "metadata": { - "version": 1.2, - "tags": [ - "data", - "example" - ] - } -} \ No newline at end of file diff --git a/main.cpp b/main.cpp deleted file mode 100644 index bb4b970..0000000 --- a/main.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int, char**) { - try { - // 1. 载入JSON文件 - std::ifstream input_file("assets/json_example.json"); - nlohmann::ordered_json json_data = nlohmann::ordered_json::parse(input_file); - input_file.close(); - spdlog::info("JSON 成功载入!"); - - // 2. 获取不同类型的数据 - // 2.1 字符串 (String) - std::string name = json_data["name"].get(); - spdlog::info("Name: {}", name); - - // 2.2 数字 (Number) - int age = json_data["age"].get(); - double height = json_data["height_meters"].get(); - spdlog::info("Age: {}, Height: {}", age, height); - - // 2.3 布尔值 (Boolean) - bool isStudent = json_data["isStudent"].get(); - spdlog::info("Is Student: {}", isStudent); - // 2.4 null 值 - // 检查是否为null - if (json_data["middleName"].is_null()) { - spdlog::info("Middle Name: null"); - } else { - spdlog::info("Middle Name: {}", json_data["middleName"].get()); - } - - // 2.5 另外一种方法:使用 .at() 方法访问 - std::string email = json_data.at("email").get(); - spdlog::info("Email: {}", email); - - // 3 安全访问的方法 - // 3.1 .contains() 检查某个键是否存在,如果不存在则返回 false - if (json_data.contains("email")) - { - std::string email = json_data.at("email").get(); - spdlog::info("Email: {}", email); - } - if (json_data.contains("nonExistentKey")) - { - spdlog::info("nonExistentKey found!"); // 不会执行 - } - else - { - spdlog::info("'nonExistentKey' not found."); - } - - // 3.2 .value() 获取一个可能存在的键,如果不存在则返回指定默认值(第二个参数) - std::string optional_value = json_data.value("optionalKey", "default_string_value"); - int optional_int = json_data.value("optionalNumber", 42); - spdlog::info("Optional Key (string): {}", optional_value); - spdlog::info("Optional Key (int): {}", optional_int); - - // 4 对象 (Object) - nlohmann::ordered_json address_obj = json_data["address"]; - std::string street = address_obj["street"].get(); - std::string city = address_obj.value("city", "Unknown City"); // 使用 .value() 提供默认值 - bool isPrimaryAddr = address_obj.value("isPrimary", false); // 访问对象内的布尔值 - spdlog::info("Address: {}, {}", street, city); - spdlog::info("Is Primary Address: {}", isPrimaryAddr); - - // 5.1 数组 (Array) - 字符串数组 - spdlog::info("Hobbies:"); - nlohmann::ordered_json hobbies_array = json_data["hobbies"]; - for (const auto &hobby : hobbies_array) - { - spdlog::info(" - {}", hobby.get()); - } - - // 5.2 数组 (Array) - 数字数组 - spdlog::info("Scores:"); - for (const auto &score_item : json_data["scores"]) - { - if (score_item.is_number_integer()) - { - spdlog::info(" - {} (integer)", score_item.get()); - } - else if (score_item.is_number_float()) - { - spdlog::info(" - {} (float)", score_item.get()); - } - } - - // 5.3 数组 (Array) - 对象数组 - spdlog::info("Projects:"); - nlohmann::ordered_json projects_array = json_data["projects"]; - for (const auto &project : projects_array) - { - std::string projectName = project["projectName"].get(); - std::string status = project["status"].get(); - double budget = project.value("budget", 0.0); // 使用 value 获取,若不存在则为0.0 - bool isActive = project.value("isActive", false); - - spdlog::info(" ProjectName: {}", projectName); - spdlog::info(" Status: {}", status); - spdlog::info(" Budget: {}", budget); - spdlog::info(" Is Active: {}", isActive); - if (project.contains("deadline") && project["deadline"].is_null()) - { - spdlog::info(" Deadline: null"); - } - else if (project.contains("deadline")) - { - spdlog::info(" Deadline: {}", project["deadline"].get()); - } - spdlog::info("--------------------------------"); - } - // 5.4 直接访问更深层嵌套的对象和数组 - double metadata_version = json_data["metadata"]["version"].get(); - spdlog::info("Metadata Version: {}", metadata_version); - spdlog::info("Metadata Tags:"); - for (const auto &tag_json : json_data["metadata"]["tags"]) - { - std::string tag = tag_json.get(); - spdlog::info(" - {}", tag); - } - - // 6 将json数据保存为文件 - std::ofstream output_file("assets/save_json.json"); - output_file << json_data.dump(4); // 使用 dump(4) 进行格式化输出,缩进为4个空格 - output_file.close(); - spdlog::info("JSON 数据已保存到文件 assets/save_json.json"); - - } catch (const std::exception &e) { - spdlog::error("Exception: {}", e.what()); - // return EXIT_FAILURE; - } - - - return 0; -} \ No newline at end of file diff --git a/src/engine/core/game_app.cpp b/src/engine/core/game_app.cpp new file mode 100644 index 0000000..9073b59 --- /dev/null +++ b/src/engine/core/game_app.cpp @@ -0,0 +1,86 @@ +#include "game_app.h" +#include +#include + +namespace engine::core { + +GameApp::GameApp() = default; + +GameApp::~GameApp() { + if (is_running_) { + spdlog::warn("GameApp 被销毁时没有显式关闭。现在关闭。 ..."); + close(); + } +} + +void GameApp::run() { + if (!init()) { + spdlog::error("初始化失败,无法运行游戏。"); + return; + } + + while (is_running_) { + float delta_time = 0.01f; // 每帧的时间间隔(临时设定) + handleEvents(); + update(delta_time); + render(); + } + + close(); +} + +bool GameApp::init() { + spdlog::trace("初始化 GameApp ..."); + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + spdlog::error("SDL 初始化失败! SDL错误: {}", SDL_GetError()); + return false; + } + + window_ = SDL_CreateWindow("SunnyLand", 1280, 720, SDL_WINDOW_RESIZABLE); + if (window_ == nullptr) { + spdlog::error("无法创建窗口! SDL错误: {}", SDL_GetError()); + return false; + } + + sdl_renderer_ = SDL_CreateRenderer(window_, nullptr); + if (sdl_renderer_ == nullptr) { + spdlog::error("无法创建渲染器! SDL错误: {}", SDL_GetError()); + return false; + } + + is_running_ = true; + return true; +} + +void GameApp::handleEvents() { + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_EVENT_QUIT) { + is_running_ = false; + } + } +} + +void GameApp::update(float /* delta_time */) { + // 游戏逻辑更新,暂时为空 +} + +void GameApp::render() { + // 渲染代码,暂时为空 +} + +void GameApp::close() { + spdlog::trace("关闭 GameApp ..."); + if (sdl_renderer_ != nullptr) { + SDL_DestroyRenderer(sdl_renderer_); + sdl_renderer_ = nullptr; + } + if (window_ != nullptr) { + SDL_DestroyWindow(window_); + window_ = nullptr; + } + SDL_Quit(); + is_running_ = false; +} + +} // namespace engine::core \ No newline at end of file diff --git a/src/engine/core/game_app.h b/src/engine/core/game_app.h new file mode 100644 index 0000000..c00448b --- /dev/null +++ b/src/engine/core/game_app.h @@ -0,0 +1,42 @@ +#pragma once + +// 前向声明, 减少头文件的依赖,增加编译速度 +struct SDL_Window; +struct SDL_Renderer; + +namespace engine::core { + +/** + * @brief 主游戏应用程序类,初始化SDL,管理游戏循环。 + */ +class GameApp final { +private: + SDL_Window* window_ = nullptr; + SDL_Renderer* sdl_renderer_ = nullptr; + bool is_running_ = false; + +public: + GameApp(); + ~GameApp(); + + /** + * @brief 运行游戏应用程序,其中会调用init(),然后进入主循环,离开循环后自动调用close()。 + */ + void run(); + + // 禁止拷贝和移动 + GameApp(const GameApp&) = delete; + GameApp& operator=(const GameApp&) = delete; + GameApp(GameApp&&) = delete; + GameApp& operator=(GameApp&&) = delete; + +private: + [[nodiscard]] bool init(); + void handleEvents(); + void update(float delta_time); + void render(); + void close(); +}; + +} // namespace engine::core + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..8aac225 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,7 @@ +#include "engine/core/game_app.h" + +int main(int /* argc */, char* /* argv */[]) { + engine::core::GameApp app; + app.run(); + return 0; +} \ No newline at end of file