完成窗口创建

This commit is contained in:
Ziyu
2025-06-16 14:44:47 +08:00
parent ed38fcee73
commit 3bef8e84ba
7 changed files with 139 additions and 229 deletions
+4 -1
View File
@@ -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}
-39
View File
@@ -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"]
}
}
-46
View File
@@ -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"
]
}
}
-143
View File
@@ -1,143 +0,0 @@
#include <iostream>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3_mixer/SDL_mixer.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <glm/glm.hpp>
#include <nlohmann/json.hpp>
#include <spdlog/spdlog.h>
#include <fstream>
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<std::string>();
spdlog::info("Name: {}", name);
// 2.2 数字 (Number)
int age = json_data["age"].get<int>();
double height = json_data["height_meters"].get<double>();
spdlog::info("Age: {}, Height: {}", age, height);
// 2.3 布尔值 (Boolean)
bool isStudent = json_data["isStudent"].get<bool>();
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<std::string>());
}
// 2.5 另外一种方法:使用 .at() 方法访问
std::string email = json_data.at("email").get<std::string>();
spdlog::info("Email: {}", email);
// 3 安全访问的方法
// 3.1 .contains() 检查某个键是否存在,如果不存在则返回 false
if (json_data.contains("email"))
{
std::string email = json_data.at("email").get<std::string>();
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>();
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<std::string>());
}
// 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<int>());
}
else if (score_item.is_number_float())
{
spdlog::info(" - {} (float)", score_item.get<double>());
}
}
// 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>();
std::string status = project["status"].get<std::string>();
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<std::string>());
}
spdlog::info("--------------------------------");
}
// 5.4 直接访问更深层嵌套的对象和数组
double metadata_version = json_data["metadata"]["version"].get<double>();
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<std::string>();
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;
}
+86
View File
@@ -0,0 +1,86 @@
#include "game_app.h"
#include <SDL3/SDL.h>
#include <spdlog/spdlog.h>
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
+42
View File
@@ -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
+7
View File
@@ -0,0 +1,7 @@
#include "engine/core/game_app.h"
int main(int /* argc */, char* /* argv */[]) {
engine::core::GameApp app;
app.run();
return 0;
}