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
Bắt đầu

Trang này hướng dẫn build njin, chạy game mẫu và viết chương trình đầu tiên. Chưa cài trình biên dịch, CMake hay Ninja? Làm theo Cài môi trường trước, có hướng dẫn cho từng hệ điều hành. Chưa quen C++, CMake hay shader? Nhóm bài Kiến thức nền: học trước khi làm game dạy từ đầu, và không cần njin.

Yêu cầu

  • CMake 3.28 trở lên
  • Trình biên dịch C++20. Môi trường phát triển chính là GCC trong w64devkit trên Windows. MSVC và GCC trên Linux có trong CI (.github/workflows/build.yml)
  • Ninja (không cần nếu dùng MSVC với generator của Visual Studio)
  • Git: CMake tải raylib 6.0, EnTT v4.0.0 và (cho njin_inspector) Dear ImGui về khi cấu hình lần đầu
  • Linux: thêm các thư viện phát triển X11 và OpenGL, ví dụ trên Ubuntu: sudo apt install ninja-build libgl1-mesa-dev libx11-dev libxrandr-dev libxi-dev libxcursor-dev libxinerama-dev

Lấy mã nguồn

git clone https://github.com/tptindev/njin.git
cd njin

Build và chạy

Trên Windows, hai script ở thư mục gốc lo hết:

Script Việc làm
build.bat Cấu hình bằng Ninja (Debug), cập nhật compile_commands.json cho clangd, rồi build
run.bat Build target njin_sandbox và chạy build\bin\njin_sandbox.exe
build\bin\njin_pong.exe Game Pong mẫu, build cùng build.bat

Trên mọi hệ điều hành, dùng preset trong CMakePresets.json, không cần nhớ tham số:

Preset Thư mục build Việc làm
debug build/ Ninja, Debug. Game có kết nối debug tới njin_inspector
release build-release/ Ninja, Release. Tối ưu, không có kết nối debug
cmake --preset debug
cmake --build --preset debug --target njin_sandbox
build\bin\njin_sandbox.exe

Bỏ --target để build mọi thứ (game mẫu, njin_inspector). Dùng MSVC thì không cần preset: cmake -S . -B build -A x64 rồi cmake --build build --config Release.

Ghi chú
run.bat chạy game với thư mục làm việc là thư mục gốc của repo. Đường dẫn tương đối như assets/player.png được tính từ đó trước, rồi từ thư mục chứa exe. Dùng njin_add_assets() trong CMake để thư mục assets của game được copy cạnh exe mỗi lần build, xem Cửa sổ, file và lưu game.

Chương trình nhỏ nhất

#include <njin.h>
int main() {
const njin::config cfg{.title = "njin",
.width = 1280.0f,
.height = 720.0f,
.target_fps = 60.0f};
njin::context *ctx = njin::create(cfg);
njin::run(*ctx);
return 0;
}
void run(context &ctx)
Chạy vòng lặp chính cho đến khi cửa sổ đóng.
context * create(const config &cfg)
Mở cửa sổ và trả về context của engine.
void destroy(context *ctx)
Giải phóng mọi tài nguyên của engine và đóng cửa sổ.
Cấu hình cửa sổ và vòng lặp, truyền vào create().
Definition njin_cfg.h:11

Ba hàm cần biết:

  • create() mở cửa sổ và trả về context của engine.
  • run() chạy vòng lặp đến khi cửa sổ đóng.
  • destroy() giải phóng mọi tài nguyên.

Chương trình này mở một cửa sổ trống. Để làm được điều gì đó, bạn viết module: xem Module, system và phase.

Thêm module của game

Tạo module trong một file .cpp, đăng ký nó trong main trước run():

#include <njin.h>
namespace {
// Một system là hàm thường nhận context&.
void spawn(njin::context &ctx) {
entt::registry &registry = njin::world(ctx);
const entt::entity entity = registry.create();
registry.emplace<njin::transform>(entity);
NJIN_INFO("đã tạo entity đầu tiên");
}
// setup được gọi đúng một lần khi đăng ký module.
void setup(njin::context &ctx) {
}
} // namespace
njin::mod_desc hello_module() {
return {.name = "hello", .setup = setup};
}
int main() {
const njin::config cfg{.title = "hello",
.width = 800.0f,
.height = 600.0f,
.target_fps = 60.0f};
njin::context *ctx = njin::create(cfg);
njin::mod_register(*ctx, hello_module()); // trước run
njin::run(*ctx);
return 0;
}
#define NJIN_INFO(...)
Ghi log mức info. Tham số giống printf.
Definition njin_log.h:98
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.
void mod_register(context &ctx, const mod_desc &desc)
Chạy setup của module và đưa các system của nó vào lịch chạy.
entt::registry & world(context &ctx)
Trả về registry của EnTT chứa mọi entity và component của game.
@ phase_startup
Một lần, trước frame đầu tiên.
Definition _mod.h:32
Mô tả một module: một nhóm system có tên.
Definition _mod.h:67
Vị trí, góc xoay và tỉ lệ của một entity trong thế giới.
Definition _comps.h:14

Với một game trong src/games/<tên>/, file CMakeLists.txt của nó cần:

add_executable(my_game main.cpp modules/hello.cpp)
# njin::rt kéo theo njin::api (và thư mục include của nó).
target_link_libraries(my_game PRIVATE njin::rt njin_warnings)

rồi thêm add_subdirectory(src/games/my_game) vào CMakeLists.txt gốc.

Bước tiếp theo