njin
Engine 2D gọn nhẹ để tự tay làm game theo ý mình. Vibe coding cũng ổn luôn
Loading...
Searching...
No Matches
JSON và lưu game

njin::json_value đọc và ghi JSON: lưu game, file cấu hình, bảng số liệu của game. Đây cũng là kiểu của thuộc tính đọc từ Tiled và LDtk (xem Level từ Tiled và LDtk).

#include <njin.h>
#include <string>
#include <vector>
namespace {
struct progress {
njin::i32 level = 1;
njin::f32 volume = 0.8f;
std::vector<std::string> items;
};
progress p;
std::string file(njin::context &ctx) { return njin::save_path(ctx, "save.json"); }
void save(njin::context &ctx) {
for (const std::string &it : p.items)
items.push(it);
doc.set("version", 1).set("level", p.level).set("volume", p.volume).set("items", std::move(items));
njin::json_save(file(ctx).c_str(), doc); // ghi ra file tạm rồi đổi tên: không bao giờ hỏng nửa chừng
}
void load(njin::context &ctx) {
if (!njin::json_load(file(ctx).c_str(), doc))
return; // lần chạy đầu: giữ giá trị mặc định
// Khóa không có đọc ra null, nên mỗi lần đọc có giá trị dự phòng: bản lưu
// cũ chưa có "volume" vẫn nạp được.
p.level = doc["level"].int_or(1);
p.volume = doc["volume"].f32_or(0.8f);
p.items.clear();
for (const njin::json_value &it : doc["items"].items)
p.items.push_back(it.string_or(""));
}
void setup(njin::context &ctx) {
}
} // namespace
njin::mod_desc save_module() { return {.name = "save", .setup = setup}; }
std::string save_path(const context &ctx, const char *file_name)
Đường dẫn đầy đủ của một file lưu game, trong thư mục riêng của người dùng.
bool json_save(const char *path, const json_value &value, bool pretty=true)
Ghi một giá trị ra file JSON, tạo thư mục cha nếu cần.
bool json_load(const char *path, json_value &out)
Đọc và phân tích một file JSON.
void ecs_register(context &ctx, sys_phase phase, sys_fnc fnc, const char *name=nullptr)
Thêm một system vào lịch chạy của một phase.
@ phase_shutdown
Một lần, sau khi cửa sổ đóng.
Definition _mod.h:40
@ phase_startup
Một lần, trước frame đầu tiên.
Definition _mod.h:32
std::int32_t i32
Số nguyên có dấu 32 bit.
Definition _types.h:14
float f32
Số thực 32 bit.
Definition _types.h:28
Một giá trị JSON: null, bool, số, chuỗi, mảng hoặc object.
Definition njin_json.h:33
i32 int_or(i32 fallback) const
Số nguyên (làm tròn về 0), hoặc fallback.
Definition njin_json.h:124
json_value & push(json_value value)
Thêm phần tử vào cuối mảng.
f32 f32_or(f32 fallback) const
Số thực 32 bit, hoặc fallback.
Definition njin_json.h:122
static json_value make_array()
Một mảng rỗng.
Definition njin_json.h:75
static json_value make_object()
Một object rỗng.
Definition njin_json.h:69
json_value & set(std::string_view key, json_value value)
Đặt thành viên key (thay nếu đã có, thêm vào cuối nếu chưa).
Mô tả một module: một nhóm system có tên.
Definition _mod.h:67

Đọc

  • doc["key"] và doc[i] không bao giờ lỗi: khóa không có, sai kiểu, ngoài mảng đều trả về một giá trị null. Đọc sâu bao nhiêu tầng cũng an toàn: doc["a"]["b"]["c"].
  • Lấy giá trị kèm dự phòng: int_or(), f32_or(), number_or(), bool_or(), string_or(). Nhờ vậy bản lưu cũ thiếu khóa mới vẫn nạp được.
  • Duyệt: mảng qua items, object qua members (giữ đúng thứ tự trong file).
  • is(), has(), size() để kiểm tra.

Ghi

  • json_value::make_object(), json_value::make_array() tạo giá trị rỗng.
  • set(key, value) đặt thành viên (thay nếu đã có, vị trí giữ nguyên), push(value) thêm vào mảng. Cả hai trả về chính giá trị đó, nên gọi nối tiếp được.
  • Số nguyên được ghi không có phần thập phân; số thực được ghi ngắn nhất mà vẫn đọc lại đúng (0.1 chứ không phải 0.10000000000000001).

File

Hàm Việc làm
njin::json_load() Đọc và phân tích file. Lỗi được ghi log kèm vị trí byte
njin::json_save() Ghi file qua một file tạm rồi đổi tên: mất điện giữa chừng không làm hỏng bản cũ
njin::json_parse() Phân tích một chuỗi
njin::json_dump() Viết ra chuỗi, có thụt lề hoặc một dòng

Lưu game nên nằm trong thư mục của người dùng: njin::save_path() (xem Cửa sổ, file và lưu game).