simplify code & add `entity_move()`
This commit is contained in:
parent
510d53e13b
commit
d8f5b63500
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
int sign(int n);
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
13
src/main.c
13
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;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#include "util.h"
|
||||
|
||||
int
|
||||
sign(int n)
|
||||
{
|
||||
return (n > 0) - (n < 0);
|
||||
}
|
Loading…
Reference in New Issue