A game engine for top-down 2D RPG games.
rpg game-engine raylib c99
1#include <keraforge.h> 2#include <raylib.h> 3#include <stdlib.h> 4#include <string.h> 5#include <math.h> 6 7 8struct _kf_tiles kf_tiles = {0}; 9 10 11struct kf_world *kf_world_new(u32 width, u32 height, kf_tileid_t fill) 12{ 13 const size_t len = sizeof(kf_tileid_t) * width * height; 14 struct kf_world *world = malloc(sizeof(struct kf_world) + len); 15 world->revision = 0; 16 world->width = width; 17 world->height = height; 18 memset(world->map, fill, len); 19 return world; 20} 21 22size_t kf_world_getsize(struct kf_world *world) 23{ 24 return sizeof(struct kf_world) + sizeof(kf_tileid_t)*world->width*world->height; 25} 26 27kf_tileid_t *kf_world_gettile(struct kf_world *world, u32 x, u32 y) 28{ 29 return &world->map[y*world->width + x]; 30} 31 32void kf_world_drawcolliders(struct kf_world *world, struct kf_actor *player, Camera2D camera) 33{ 34 Rectangle r = { 35 player->pos.x + (player->size.x / 2) + player->sizeoffset.x, 36 player->pos.y + (player->size.y / 2) + player->sizeoffset.y, 37 player->size.x, 38 player->size.y 39 }; 40 41 DrawRectangleLinesEx(r, 1, BLUE); 42 43 const Vector2 start = GetScreenToWorld2D((Vector2){0, 0}, camera); 44 const Vector2 end = GetScreenToWorld2D((Vector2){GetScreenWidth(), GetScreenHeight()}, camera); 45 const u32 sx = fmax(0, floorf(start.x / KF_TILE_SIZE_PX)); 46 const u32 sy = fmax(0, floorf(start.y / KF_TILE_SIZE_PX)); 47 const u32 ex = fmin(world->width, ceilf(end.x / KF_TILE_SIZE_PX)); 48 const u32 ey = fmin(world->height, ceilf(end.y / KF_TILE_SIZE_PX)); 49 const size_t down = world->width - ex + sx - 1; /* number of indexes to add to reach the next tile down */ 50 kf_tileid_t *tile = kf_world_gettile(world, sx, sy); 51 52 /* check if any tiles will collide with the actor's rect */ 53 const f32 trx = sx * KF_TILE_SIZE_PX; 54 Rectangle tr = { 55 trx, 56 sy * KF_TILE_SIZE_PX, 57 KF_TILE_SIZE_PX, 58 KF_TILE_SIZE_PX, 59 }; /* tile rect */ 60 u32 x; 61 62 for (u32 y = sy ; y <= ey ; y++) 63 { 64 for (x = sx ; x <= ex ; x++) 65 { 66 if (kf_tiles.collide[*tile]) 67 DrawRectangleLinesEx(tr, 1, CheckCollisionRecs(r, tr) ? RED : BLACK); 68 69 tile++; /* shift tile pointer to the right */ 70 tr.x += KF_TILE_SIZE_PX; 71 } 72 tile += down; /* shift tile pointer down */ 73 tr.x = trx; 74 tr.y += KF_TILE_SIZE_PX; 75 } 76} 77 78void kf_world_draw(struct kf_world *world, Camera2D camera) 79{ 80 const Vector2 start = GetScreenToWorld2D((Vector2){0, 0}, camera); 81 const Vector2 end = GetScreenToWorld2D((Vector2){GetScreenWidth(), GetScreenHeight()}, camera); 82 const u32 sx = fmax(0, floorf(start.x / KF_TILE_SIZE_PX)); 83 const u32 sy = fmax(0, floorf(start.y / KF_TILE_SIZE_PX)); 84 const u32 ex = fmin(world->width, ceilf(end.x / KF_TILE_SIZE_PX)); 85 const u32 ey = fmin(world->height, ceilf(end.y / KF_TILE_SIZE_PX)); 86 const size_t down = world->width - ex + sx; /* number of indexes to add to reach the next tile down */ 87 kf_tileid_t *tile = kf_world_gettile(world, sx, sy); 88 u32 x; 89 for (u32 y = sy ; y < ey ; y++) 90 { 91 for (x = sx ; x < ex ; x++) 92 { 93 DrawRectangle( 94 (int)x * KF_TILE_SIZE_PX, 95 (int)y * KF_TILE_SIZE_PX, 96 KF_TILE_SIZE_PX, 97 KF_TILE_SIZE_PX, 98 kf_tiles.mapcol[*tile] 99 ); 100 tile++; /* shift tile pointer to the right */ 101 } 102 tile += down; /* shift tile pointer down */ 103 } 104}