From d8f5b63500f4357cdf0c58c370d680254a450a28 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Fri, 11 Jun 2021 12:47:16 +0200 Subject: [PATCH] simplify code & add `entity_move()` --- CMakeLists.txt | 4 +++- include/entity.h | 17 +++++++++++----- include/layers.h | 2 +- include/util.h | 3 +++ src/entity/collide.c | 11 +++------- src/entity/draw_hitbox.c | 3 +-- src/entity/init.c | 9 ++++----- src/entity/move.c | 43 ++++++++++++++++++++++++++++++++++++++++ src/main.c | 13 +++++------- src/util.c | 7 +++++++ 10 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 include/util.h create mode 100644 src/entity/move.c create mode 100644 src/util.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4842738..9bf4933 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,10 @@ set(SOURCES src/entity/collide.c src/entity/draw_hitbox.c src/entity/init.c + src/entity/move.c src/wall/init.c src/player/init.c + src/util.c ) set(ASSETS @@ -28,7 +30,7 @@ set(FLAGS -Wall -Wextra -Wshadow -Wswitch-default -Wswitch-enum -Wunreachable-code -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Werror-implicit-function-declaration - -fms-extensions -std=c99 -O3 + -fplan9-extensions -std=c99 -O3 ) fxconv_declare_assets(${ASSETS} WITH_METADATA) diff --git a/include/entity.h b/include/entity.h index a8a8919..fb9c429 100644 --- a/include/entity.h +++ b/include/entity.h @@ -15,9 +15,16 @@ struct Entity { #define ENTITY_GRID_SIZE 256 extern struct Entity *g_entity_grid[ENTITY_GRID_SIZE]; -void entity_init(void *restrict entity, int x, int y, int hb_x, int hb_y, - int hb_w, int hb_h, int layer, color_t hb_color); -void entity_deinit(void *restrict entity); -void entity_draw_hitbox(void *restrict entity); +void entity_init(struct Entity *, int x, int y, int hb_x, int hb_y, int hb_w, + int hb_h, int layer, color_t hb_color); +void entity_deinit(struct Entity *); +void entity_draw_hitbox(struct Entity *); void entity_grid_draw_hitboxes(void); -struct Entity *entity_collide(void *restrict entity, int mask); +/* return first entity colliding on mask */ +struct Entity *entity_collide(struct Entity *, int mask); +/* return bool */ +int entity_collide_with(struct Entity *self, struct Entity *other, int mask); +/* return bitmask + * bit 1: collide on x + * bit 2: collide on y */ +int entity_move(struct Entity *e, int mask, int move_x, int move_y); diff --git a/include/layers.h b/include/layers.h index d3621f2..58ecb43 100644 --- a/include/layers.h +++ b/include/layers.h @@ -4,6 +4,6 @@ enum Layers { L_NONE = 0, L_SOLID = 1 << 1, L_SEMISOLID = 1 << 2, - L_HARMFULL = 1 << 3, + L_HARMFUL = 1 << 3, L_PUSHABLE = 1 << 4, }; diff --git a/include/util.h b/include/util.h new file mode 100644 index 0000000..b4c3874 --- /dev/null +++ b/include/util.h @@ -0,0 +1,3 @@ +#pragma once + +int sign(int n); diff --git a/src/entity/collide.c b/src/entity/collide.c index eacc281..87428ea 100644 --- a/src/entity/collide.c +++ b/src/entity/collide.c @@ -1,12 +1,8 @@ #include "entity.h" -static int entity_collide_with(struct Entity *restrict, struct Entity *restrict, - int mask); - struct Entity * -entity_collide(void *restrict entity, int mask) +entity_collide(struct Entity *e, int mask) { - struct Entity *const e = entity; int i; i = ENTITY_GRID_SIZE; @@ -18,9 +14,8 @@ entity_collide(void *restrict entity, int mask) } /* axis aligned bounding box collision checking */ -static int -entity_collide_with(struct Entity *restrict self, struct Entity *restrict other, - int mask) +int +entity_collide_with(struct Entity *self, struct Entity *other, int mask) { const int sx = self->x + self->hb_x; const int sy = self->y + self->hb_y; diff --git a/src/entity/draw_hitbox.c b/src/entity/draw_hitbox.c index 4f0629f..87bcb51 100644 --- a/src/entity/draw_hitbox.c +++ b/src/entity/draw_hitbox.c @@ -2,9 +2,8 @@ #include void -entity_draw_hitbox(void *restrict entity) +entity_draw_hitbox(struct Entity *e) { - const struct Entity *const e = entity; const int x = e->x + e->hb_x; const int y = e->y + e->hb_y; drect_border(e->x, e->y, e->x + 2, e->y + 2, C_NONE, 1, e->hb_color); diff --git a/src/entity/init.c b/src/entity/init.c index 544c6fa..c0f5369 100644 --- a/src/entity/init.c +++ b/src/entity/init.c @@ -5,11 +5,10 @@ struct Entity *g_entity_grid[ENTITY_GRID_SIZE]; void -entity_init(void *restrict entity, int x, int y, int hb_x, int hb_y, int hb_w, +entity_init(struct Entity *e, int x, int y, int hb_x, int hb_y, int hb_w, int hb_h, int layer, color_t hb_color) { static int init_grid = 1; - struct Entity *const e = entity; int i; e->x = x; e->y = y; @@ -32,17 +31,17 @@ entity_init(void *restrict entity, int x, int y, int hb_x, int hb_y, int hb_w, while (i-- > 0) if (g_entity_grid[i] == NULL) break; - g_entity_grid[i] = entity; + g_entity_grid[i] = e; } void -entity_deinit(void *restrict entity) +entity_deinit(struct Entity *e) { int i; /* remove from grid */ i = ENTITY_GRID_SIZE; while (i-- > 0) - if (g_entity_grid[i] == entity) + if (g_entity_grid[i] == e) break; g_entity_grid[i] = NULL; } diff --git a/src/entity/move.c b/src/entity/move.c new file mode 100644 index 0000000..4cd54a4 --- /dev/null +++ b/src/entity/move.c @@ -0,0 +1,43 @@ +#include "entity.h" +#include "util.h" + +/* only provide non-nul value on `move_x` OR `move_y` */ +static int entity_move_single_axis(struct Entity *, int mask, int move_x, + int move_y); + +int +entity_move(struct Entity *e, int mask, int move_x, int move_y) +{ + int collided = 0; + + collided |= entity_move_single_axis(e, mask, move_x, 0); + collided |= entity_move_single_axis(e, mask, 0, move_y) << 1; + + return collided; +} + +static int +entity_move_single_axis(struct Entity *e, int mask, int move_x, int move_y) +{ + struct Entity *other; + int collided = 0; + const int sign_move_x = sign(move_x); + const int sign_move_y = sign(move_y); + + if (!move_x && !move_y) + return 0; + + e->x += move_x; + e->y += move_y; + do { + other = entity_collide(e, mask); + if (other != NULL) + collided = 1; + while (entity_collide_with(e, other, mask)) { + e->x -= sign_move_x; + e->y -= sign_move_y; + } + } while (other != NULL); + + return collided; +} diff --git a/src/main.c b/src/main.c index f3757cc..803e56f 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ main(void) struct Player player; struct Player newb; struct Wall walls[5]; + int collided = 0; player_init(&player, 16, 32); player_init(&newb, 64, 128); @@ -21,18 +22,14 @@ main(void) wall_init(&walls[4], DWIDTH / 2 - 24, DHEIGHT - 64, 48, 48); do { - const int previous_x = player.x; - const int previous_y = player.y; dclear(C_BLACK); entity_grid_draw_hitboxes(); + dprint(2, 2, C_WHITE, "%d", collided); dupdate(); clearevents(); - player.x += keydown(KEY_RIGHT) - keydown(KEY_LEFT); - player.y += keydown(KEY_DOWN) - keydown(KEY_UP); - if (entity_collide(&player, L_SOLID) != NULL) { - player.x = previous_x; - player.y = previous_y; - } + collided = entity_move(&player, L_SOLID, + keydown(KEY_RIGHT) - keydown(KEY_LEFT), + keydown(KEY_DOWN) - keydown(KEY_UP)); } while (!keydown(KEY_EXIT)); return; diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..f48d07b --- /dev/null +++ b/src/util.c @@ -0,0 +1,7 @@ +#include "util.h" + +int +sign(int n) +{ + return (n > 0) - (n < 0); +}