diff --git a/Makefile b/Makefile index 4e886e4..f264ce9 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CC=gcc .PHONY: build clean run all -all: main glowing_cube +all: main main: main.c ./lib/libraylib.a $(CC) $(CFLAGS) -Iinclude/ -lm main.c -o main ./lib/libraylib.a diff --git a/config.h b/config.h new file mode 100644 index 0000000..dc1295e --- /dev/null +++ b/config.h @@ -0,0 +1,89 @@ + +SpriteSheet knight = { + .name = "blue_knight", + .texture = {0}, + .anim_count = 8, + .width = 1152, + .height = 1536, +}; + +const u16 cell_size = 192; +SpriteAnimation knight_idle = { + .name = "idle", + .pos_x = 0, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; + +SpriteAnimation knight_run = { + .name = "run", + .pos_x = cell_size, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; + +SpriteAnimation knight_attack_side1 = { + .name = "attack_side1", + .pos_x = cell_size * 2, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; + +SpriteAnimation knight_attack_side2 = { + .name = "attack_side2", + .pos_x = cell_size * 3, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; + +SpriteAnimation knight_attack_front1 = { + .name = "attack_front1", + .pos_x = cell_size * 4, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; + +SpriteAnimation knight_attack_front2 = { + .name = "attack_front2", + .pos_x = cell_size * 5, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; + +SpriteAnimation knight_attack_back1 = { + .name = "attack_back1", + .pos_x = cell_size * 6, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; + +SpriteAnimation knight_attack_back2 = { + .name = "attack_back2", + .pos_x = cell_size * 7, + .pos_y = 0, + .rows = 1, + .cols = 6, + .width = 192, + .height = 192, +}; diff --git a/lib.h b/lib.h new file mode 100644 index 0000000..309d403 --- /dev/null +++ b/lib.h @@ -0,0 +1,17 @@ +#include +#include + +typedef uint8_t u8; +// typedef char16_t c16; +typedef uint16_t u16; +typedef int16_t i16; +typedef int32_t b32; +typedef int32_t i32; +typedef uint32_t u32; +typedef uint64_t u64; +typedef float f32; +typedef double f64; +typedef uintptr_t uptr; +typedef char byte; +typedef ptrdiff_t size; +typedef size_t usize; diff --git a/main.c b/main.c index 7c0fb7a..363764e 100644 --- a/main.c +++ b/main.c @@ -1,18 +1,112 @@ -#include "raylib.h" +#include "include/raylib.h" +#include "include/raymath.h" +#include +#include +#include "lib.h" +#include "sprites.h" +#include "config.h" + +#define TEXTURES_BUF_SIZE 16 +#define TARGET_FPS 120 +#define ANIM_SPEED 8 typedef struct { + int frame_count; + int anim_frames; + bool is_attacking; Vector2 knight_pos; + Rectangle knight_rect; } GameState; -void Init(GameState *state); -// { -// } +typedef struct { + Texture2D *textures; +} Assets; -void Draw(GameState *state); -// { -// ClearBackground(RAYWHITE); -// DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); -// } +Assets Init() { + Assets assets = { 0 }; + assets.textures = malloc(sizeof(Texture2D) * TEXTURES_BUF_SIZE); + assets.textures[0] = LoadTexture("assets/Terrain/Ground/Tilemap_Flat.png"); + assets.textures[1] = LoadTexture("assets/Factions/Knights/Troops/Warrior/Blue/Warrior_Blue.png"); + return assets; +} + +void Update(GameState *state, Camera2D cam, float dt) { + (void)cam; + int anim_speed = 10; + if (state->frame_count % (TARGET_FPS/anim_speed) == 0) { + state->anim_frames++; + if (state->anim_frames > 5) { + state->anim_frames = 0; + } + state->knight_rect.x = (float)state->anim_frames * (float)state->knight_rect.width; + } + float speed = 250.0f * dt; + Vector2 input_vel = {0}; + if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) { + input_vel.x = 1; + } + if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) { + input_vel.x = -1; + } + if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) { + input_vel.y = -1; + } + if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) { + input_vel.y = 1; + } + static int attacking_frames = 0; + if (IsKeyPressed(KEY_SPACE)) { + state->is_attacking = true; + attacking_frames = state->anim_frames; + } + input_vel = Vector2Normalize(input_vel); + input_vel = Vector2Scale(input_vel, speed); + state->knight_pos = Vector2Add(state->knight_pos, input_vel); + if (state->is_attacking) { + if (state->anim_frames - attacking_frames > 5) { + state->is_attacking = false; + state->knight_rect.y = 0; + } else { + state->knight_rect.y = 192 * 2; + } + } else { + if (input_vel.x != 0 || input_vel.y != 0) { + state->knight_rect.y = 192; + } else { + state->knight_rect.y = 0; + } + } +} + +void Draw(GameState *state, Assets assets, Camera2D cam, float dt) { + (void)cam; + (void)dt; + ClearBackground((Color){ 100, 149, 237, 255 }); + + int size = 32; + int topx = 300; + int topy = 32; + for (int col = 0; col < size; col++) { + for (int row = 0; row < size; row++) { + int atlas_col = 0; + int atlas_row = 0; + if (col == size - 1) { + atlas_col = 5; + } else if (col > 0) { + atlas_col = (col % 4) + 1; + } + if (row == size - 1) { + atlas_row = 5; + } else if (row > 0) { + atlas_row = (row % 4) + 1; + } + Vector2 pos = {32 * col + topx, 32 * row + topy}; + Rectangle src_rect = {32 * atlas_col, 32 * atlas_row, 32, 32}; + DrawTextureRec(assets.textures[0], src_rect, pos, WHITE); + } + } + DrawTextureRec(assets.textures[1], state->knight_rect, state->knight_pos, WHITE); +} int main(void) { const int screen_width = 1600; @@ -23,81 +117,44 @@ int main(void) { int monitor = GetCurrentMonitor(); int monitor_width = GetMonitorWidth(monitor); int monitor_height = GetMonitorHeight(monitor); - SetWindowPosition(monitor_width / 2 - screen_width / 2, - monitor_height / 2 - screen_height / 2); + int win_pos_x = monitor_width / 2 - screen_width / 2; + int win_pos_y = monitor_height / 2 - screen_height / 2; + SetWindowPosition(win_pos_x, win_pos_y); - SetTargetFPS(60); + SetTargetFPS(TARGET_FPS); GameState state = {0}; Camera2D cam = {0}; + state.knight_rect = (Rectangle) {0, 0, 1152 / 6, 1536 / 8}; // Vector2 offset; // Camera offset (displacement from target) // Vector2 target; // Camera target (rotation and zoom origin) // float rotation; // Camera rotation in degrees cam.zoom = 1.0f; - Texture2D ground = LoadTexture("assets/Terrain/Ground/Tilemap_Flat.png"); - Texture2D blue_knight_warrior = - LoadTexture("assets/Factions/Knights/Troops/Warrior/Blue/Warrior_Blue.png"); + Assets assets = Init(); - int framesCounter = 0; - int knight_speed = 10.1f; + // const int idle while (!WindowShouldClose()) { - framesCounter++; + state.frame_count++; + float dt = GetFrameTime(); - if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) { - state.knight_pos.x += knight_speed; - } - if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) { - state.knight_pos.x -= knight_speed; - } - if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) { - state.knight_pos.y -= knight_speed; - } - if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) { - state.knight_pos.y += knight_speed; - } + Update(&state, cam, dt); BeginDrawing(); { BeginMode2D(cam); { - ClearBackground((Color){ 100, 149, 237, 255 }); - // Draw(&state); - int size = 32; - int topx = 300; - int topy = 32; - for (int col = 0; col < size; col++) { - for (int row = 0; row < size; row++) { - int atlas_col = 0; - int atlas_row = 0; - if (col == size - 1) { - atlas_col = 5; - } else if (col > 0) { - atlas_col = (col % 4) + 1; - } - if (row == size - 1) { - atlas_row = 5; - } else if (row > 0) { - atlas_row = (row % 4) + 1; - } - Vector2 pos = {32 * col + topx, 32 * row + topy}; - Rectangle src_rect = {32 * atlas_col, 32 * atlas_row, 32, 32}; - DrawTextureRec(ground, src_rect, pos, WHITE); - } - } - DrawTextureRec(blue_knight_warrior, - (Rectangle){0, 0, 1152 / 6, 1536 / 8}, - state.knight_pos, - // (Vector2){100, 100}, - WHITE); + Draw(&state, assets, cam, dt); } EndMode2D(); } EndDrawing(); } - UnloadTexture(ground); + for (int i = 0; i < TEXTURES_BUF_SIZE; i++) { + UnloadTexture(assets.textures[0]); + } CloseWindow(); return 0; } diff --git a/sprites.h b/sprites.h new file mode 100644 index 0000000..29f1ce6 --- /dev/null +++ b/sprites.h @@ -0,0 +1,26 @@ +#pragma once + +#include "raylib.h" + +typedef struct { + char *name; + Texture2D texture; + u16 anim_count; + u16 width; + u16 height; +} SpriteSheet; + +typedef struct { + char* name; + u16 pos_x; + u16 pos_y; + u16 rows; + u16 cols; + u16 width; + u16 height; +} SpriteAnimation; + +typedef struct { + float time_elapsed; + int frame; +} SpriteAnimationPlayback;