simplify code & add `entity_move()`

This commit is contained in:
KikooDX 2021-06-11 12:47:16 +02:00
parent 510d53e13b
commit d8f5b63500
10 changed files with 82 additions and 30 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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,
};

3
include/util.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
int sign(int n);

View File

@ -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;

View File

@ -2,9 +2,8 @@
#include <gint/display.h>
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);

View File

@ -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;
}

43
src/entity/move.c Normal file
View File

@ -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;
}

View File

@ -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;

7
src/util.c Normal file
View File

@ -0,0 +1,7 @@
#include "util.h"
int
sign(int n)
{
return (n > 0) - (n < 0);
}