Sprite là component: gắn njin::transform và njin::sprite vào một entity, engine tự vẽ nó mỗi frame. Không cần viết system vẽ.
#include <njin.h>
namespace {
entt::entity hero = entt::null;
void spawn(njin::context &ctx) {
hero = reg.create();
.origin = {0.5f, 1.0f},
.layer = 10});
hero,
njin::sprite_anim{.frame_size = frame_size, .first = 0, .count = 4, .fps = 6});
const entt::entity tree = reg.create();
.source = {{0, 96}, {32, 32}},
.origin = {0.5f, 1.0f},
.layer = 5});
}
void control(njin::context &ctx) {
dir -= 1;
dir += 1;
if (dir != 0)
spr.flip_x = dir < 0;
if (dir != 0)
else
}
void setup(njin::context &ctx) {
}
}
njin::mod_desc sprites_module() {
return {.name =
"sprites", .setup = setup}; }
void anim_play(sprite_anim &anim, i32 first, i32 count, f32 fps, bool loop=true)
Đổi sang một animation khác trong cùng sprite sheet.
Definition _comps.h:104
const char * tr(const context &ctx, const char *key)
Chuỗi đã dịch của key trong ngôn ngữ đang dùng.
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.
entt::registry & world(context &ctx)
Trả về registry của EnTT chứa mọi entity và component của game.
@ phase_update
Mỗi frame, logic chính của game.
Definition _mod.h:35
@ phase_startup
Một lần, trước frame đầu tiên.
Definition _mod.h:32
void texture_set_filter(context &ctx, texture_handle handle, texture_filter filter)
Đổi cách lấy mẫu của texture.
texture_handle texture_load(context &ctx, const char *path)
Nạp một texture từ file ảnh.
@ filter_nearest
Giữ nguyên từng pixel, sắc cạnh. Dùng cho pixel art.
Definition njin_draw.h:198
f32 delta(const context &ctx)
Thời gian của frame trước, tính bằng giây, đã nhân với tốc độ thời gian.
float f32
Số thực 32 bit.
Definition _types.h:28
Mô tả một module: một nhóm system có tên.
Definition _mod.h:67
Animation theo frame từ một sprite sheet.
Definition _comps.h:83
Ảnh vẽ tại vị trí của entity.
Definition _comps.h:44
Định danh của một texture, tạo bởi texture_load().
Definition _types.h:146
Vector 2 chiều. Dùng cho vị trí, kích thước, độ dời.
Definition _types.h:39
Component sprite
| Trường | Ý nghĩa |
| texture | Ảnh cần vẽ |
| source | Vùng trong ảnh (pixel). Kích thước 0 là cả ảnh |
| origin | Điểm neo theo tỉ lệ: {0.5, 0.5} là tâm (mặc định), {0.5, 1} là giữa đáy |
| tint | Màu nhân vào ảnh. a < 1 là trong suốt |
| layer | Lớp vẽ: lớp nhỏ vẽ trước, lớp lớn đè lên |
| flip_x, flip_y | Lật ảnh |
| visible | Ẩn tạm mà không cần gỡ component |
Sprite dùng cả ba trường của njin::transform: pos là nơi điểm neo rơi vào, rot là góc xoay quanh điểm neo, scale là tỉ lệ.
Thứ tự vẽ
Module sprite của engine vẽ trong phase_render:
- Mọi sprite, tilemap và particle, theo layer tăng dần. Cùng lớp thì tilemap vẽ trước, rồi sprite, rồi particle.
- Sau đó mới đến các system vẽ của game trong phase_render, nên chúng đè lên sprite.
Cùng một lớp, thứ tự giữa các sprite là thứ tự tạo entity.
Animation
Thêm njin::sprite_anim để chạy animation từ một sprite sheet: một ảnh chứa các frame cùng kích thước, đánh số từ 0 theo hàng từ trái sang phải rồi từ trên xuống.
| Trường | Ý nghĩa |
| frame_size | Kích thước một frame |
| first, count | Animation dùng frame từ first đến first + count - 1 |
| fps | Số frame mỗi giây |
| loop | Lặp lại khi hết |
| playing | Đặt false để dừng ở frame hiện tại |
| finished | Đã chạy hết (chỉ khi không lặp) |
Engine chuyển frame trong phase_post_update và ghi vào sprite.source.
Cần thời lượng riêng cho từng frame, nạp từ Aseprite, hay máy trạng thái idle/run/jump thì dùng njin::animator, xem Animation và máy trạng thái. Nháy trắng khi trúng đòn: njin::sprite_flash(), xem Particle và hiệu ứng.
Đổi animation bằng njin::anim_play(). Hàm này không làm gì nếu animation đó đang chạy, nên gọi mỗi frame được mà animation không bị bắt đầu lại liên tục.
Animation dùng thời gian đã nhân tốc độ, nên chậm lại theo njin::time_set_scale() và đứng yên khi tạm dừng.