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}