mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 06:14:08 +08:00
Load config using JSON
This commit is contained in:
@@ -42,6 +42,7 @@ set(SOURCE_FILES
|
|||||||
src/ui/managers/MainMenuUIManager.cpp
|
src/ui/managers/MainMenuUIManager.cpp
|
||||||
src/graphics/ui/UIRenderer.cpp
|
src/graphics/ui/UIRenderer.cpp
|
||||||
src/graphics/font/BitmapFont.cpp
|
src/graphics/font/BitmapFont.cpp
|
||||||
|
src/utils/ConfigLoader.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
20
assets/config.json
Normal file
20
assets/config.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"window": {
|
||||||
|
"width": 1280,
|
||||||
|
"height": 720,
|
||||||
|
"fullscreen": false,
|
||||||
|
"vsync": true,
|
||||||
|
"title": "孢子棋"
|
||||||
|
},
|
||||||
|
|
||||||
|
"render": {
|
||||||
|
"logical_width": 640,
|
||||||
|
"logical_height": 360,
|
||||||
|
"scale_mode": "integer"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ui": {
|
||||||
|
"font": "fonts/SourceHanSansSC-Regular.otf",
|
||||||
|
"font_size": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,9 @@ bool GameApplication::initialize() {
|
|||||||
SDL_Log("无法初始化 SDL_ttf: %s", SDL_GetError());
|
SDL_Log("无法初始化 SDL_ttf: %s", SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!ConfigLoader::load("assets/config.json", m_config)) {
|
||||||
|
SDL_Log("无法加载json");
|
||||||
|
}
|
||||||
// 输入管理
|
// 输入管理
|
||||||
m_inputManager = std::make_unique<InputManager>();
|
m_inputManager = std::make_unique<InputManager>();
|
||||||
// 窗口管理
|
// 窗口管理
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "scenes/base/SceneManager.h"
|
#include "scenes/base/SceneManager.h"
|
||||||
#include "input/InputManager.h"
|
#include "input/InputManager.h"
|
||||||
#include "utils/Config.h"
|
#include "utils/Config.h"
|
||||||
|
#include "utils/ConfigLoader.h"
|
||||||
#include "graphics/font/TextRenderer.h"
|
#include "graphics/font/TextRenderer.h"
|
||||||
#include "graphics/font/FontManager.h"
|
#include "graphics/font/FontManager.h"
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ private:
|
|||||||
std::unique_ptr<TextRenderer> m_textRenderer;
|
std::unique_ptr<TextRenderer> m_textRenderer;
|
||||||
std::unique_ptr<UIRenderer> m_uiRenderer;
|
std::unique_ptr<UIRenderer> m_uiRenderer;
|
||||||
|
|
||||||
WindowConfig m_config;
|
Config m_config;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameApplication();
|
GameApplication();
|
||||||
|
|||||||
@@ -10,17 +10,18 @@ WindowManager::~WindowManager() {
|
|||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowManager::Initialize(WindowConfig& config) {
|
bool WindowManager::Initialize(Config& config) {
|
||||||
m_viewport.logicalWidth = config.logicalWidth;
|
m_viewport.logicalWidth = config.render.logicalWidth;
|
||||||
m_viewport.logicalHeight = config.logicalHeight;
|
m_viewport.logicalHeight = config.render.logicalHeight;
|
||||||
// 创建窗口(支持高DPI和横屏)[3,4](@ref)
|
// 创建窗口(支持高DPI和横屏)[3,4](@ref)
|
||||||
m_window = SDL_CreateWindow(
|
m_window = SDL_CreateWindow(
|
||||||
"孢子棋", // 窗口标题,显示在标题栏上
|
config.window.title.c_str(), // 窗口标题,显示在标题栏上
|
||||||
m_viewport.logicalWidth, // 窗口的逻辑宽度(例如 800),用于统一布局,不受屏幕 DPI 影响
|
config.window.width, // 窗口的逻辑宽度(例如 800),用于统一布局,不受屏幕 DPI 影响
|
||||||
m_viewport.logicalHeight, // 窗口的逻辑高度(例如 600)
|
config.window.height, // 窗口的逻辑高度(例如 600)
|
||||||
SDL_WINDOW_HIGH_PIXEL_DENSITY | // 启用高像素密度支持(HiDPI/Retina),确保在高分屏上画面清晰
|
SDL_WINDOW_HIGH_PIXEL_DENSITY | // 启用高像素密度支持(HiDPI/Retina),确保在高分屏上画面清晰
|
||||||
SDL_WINDOW_RESIZABLE // 允许用户调整窗口大小(可拉伸)
|
SDL_WINDOW_RESIZABLE // 允许用户调整窗口大小(可拉伸)
|
||||||
);
|
);
|
||||||
|
//SDL_Log("window width %d\nwindow height %d\ntitle %s\n", config.window.width, config.window.height, config.window.title);
|
||||||
if (!m_window) {
|
if (!m_window) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"创建窗口失败: %s", SDL_GetError());
|
"创建窗口失败: %s", SDL_GetError());
|
||||||
@@ -44,7 +45,7 @@ bool WindowManager::Initialize(WindowConfig& config) {
|
|||||||
m_height,
|
m_height,
|
||||||
SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
|
SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);
|
||||||
*/
|
*/
|
||||||
SDL_SetWindowSize(m_window, UI::StartWindowWidth, UI::StartWindowHeight);
|
//SDL_SetWindowSize(m_window, UI::StartWindowWidth, UI::StartWindowHeight);
|
||||||
// 创建逻辑画布
|
// 创建逻辑画布
|
||||||
// RGBA8888: 32位色,8位红绿蓝和透明度
|
// RGBA8888: 32位色,8位红绿蓝和透明度
|
||||||
// TARGET: 纹理可作为渲染目标
|
// TARGET: 纹理可作为渲染目标
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ public:
|
|||||||
WindowManager();
|
WindowManager();
|
||||||
~WindowManager();
|
~WindowManager();
|
||||||
// 初始化
|
// 初始化
|
||||||
bool Initialize(WindowConfig& config);
|
bool Initialize(Config& config);
|
||||||
//关闭
|
//关闭
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
//清理上一帧窗口
|
//清理上一帧窗口
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ struct WindowConfig {
|
|||||||
640x360 逻辑分辨率(窗口大小的1/2)
|
640x360 逻辑分辨率(窗口大小的1/2)
|
||||||
画面更高清晰
|
画面更高清晰
|
||||||
*/
|
*/
|
||||||
int logicalWidth = 640;
|
int width = 320 * 4; // 初始窗口宽度(像素)
|
||||||
int logicalHeight = 360;
|
int height = 180 * 4; // 初始窗口高度(像素)
|
||||||
std::string windowTitle = "孢子棋";
|
std::string title = "孢子棋";
|
||||||
bool vsync = true;
|
bool vsync = true;
|
||||||
int scale = 2;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -24,6 +24,12 @@ struct WindowConfig {
|
|||||||
*/
|
*/
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
struct RenderConfig {
|
||||||
|
int logicalWidth = 640;
|
||||||
|
int logicalHeight = 360;
|
||||||
|
int scale = 2;
|
||||||
|
};
|
||||||
|
|
||||||
// 获取棋盘渲染区域信息(用于坐标转换)
|
// 获取棋盘渲染区域信息(用于坐标转换)
|
||||||
struct BoardArea {
|
struct BoardArea {
|
||||||
int x, y; // 左上角像素坐标
|
int x, y; // 左上角像素坐标
|
||||||
@@ -42,8 +48,7 @@ namespace UI
|
|||||||
constexpr int FontHeight = 8;
|
constexpr int FontHeight = 8;
|
||||||
constexpr int LogicalWidth = 640;
|
constexpr int LogicalWidth = 640;
|
||||||
constexpr int LogicalHeight = 360;
|
constexpr int LogicalHeight = 360;
|
||||||
constexpr int StartWindowWidth = 320 * 4; // 初始窗口宽度(像素)
|
|
||||||
constexpr int StartWindowHeight = 180 * 4; // 初始窗口高度(像素)
|
|
||||||
// 字体大小(逻辑像素)
|
// 字体大小(逻辑像素)
|
||||||
constexpr int DIALOG_FONT_SIZE = 14;
|
constexpr int DIALOG_FONT_SIZE = 14;
|
||||||
constexpr int UI_SMALL_FONT_SIZE = 8;
|
constexpr int UI_SMALL_FONT_SIZE = 8;
|
||||||
@@ -73,4 +78,9 @@ struct Viewport {
|
|||||||
// 逻辑画面被放大后,在窗口中的位置和大小
|
// 逻辑画面被放大后,在窗口中的位置和大小
|
||||||
// 用于 SDL_RenderTexture / 输入坐标转换
|
// 用于 SDL_RenderTexture / 输入坐标转换
|
||||||
SDL_FRect dst{};
|
SDL_FRect dst{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
WindowConfig window;
|
||||||
|
RenderConfig render;
|
||||||
};
|
};
|
||||||
59
src/utils/ConfigLoader.cpp
Normal file
59
src/utils/ConfigLoader.cpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "ConfigLoader.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
|
||||||
|
static void loadWindow(const json& j, WindowConfig& window) {
|
||||||
|
auto get = [&](const char* key, auto& out) {
|
||||||
|
if (j.contains(key))
|
||||||
|
j.at(key).get_to(out);
|
||||||
|
else {
|
||||||
|
std::cout << "Unkonw key " << key << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
get("width", window.width);
|
||||||
|
get("height", window.height);
|
||||||
|
get("title", window.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadRender(const json& j, RenderConfig& render) {
|
||||||
|
auto get = [&](const char* key, auto& out) {
|
||||||
|
if (j.contains(key))
|
||||||
|
j.at(key).get_to(out);
|
||||||
|
else {
|
||||||
|
std::cout << "Unkonw key " << key << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
get("logical_width", render.logicalWidth);
|
||||||
|
get("logical_height", render.logicalHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigLoader::load(const std::string& path, Config& config) {
|
||||||
|
std::ifstream file(path);
|
||||||
|
|
||||||
|
if (!file.is_open()) {
|
||||||
|
std::cerr << "[Config] Cannot open " << path << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
json j;
|
||||||
|
|
||||||
|
try {
|
||||||
|
file >> j;
|
||||||
|
}
|
||||||
|
catch (const json::parse_error& e) {
|
||||||
|
std::cerr << "[Config] JSON parse error: " << e.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j.contains("window")) {
|
||||||
|
loadWindow(j["window"], config.window);
|
||||||
|
}
|
||||||
|
if (j.contains("render")) {
|
||||||
|
loadRender(j["render"], config.render);
|
||||||
|
}
|
||||||
|
std::cout << "load json success!\n";
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
11
src/utils/ConfigLoader.h
Normal file
11
src/utils/ConfigLoader.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
class ConfigLoader {
|
||||||
|
public:
|
||||||
|
static bool load(const std::string& path, Config& config);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user