collision: layer and mask

This commit is contained in:
KikooDX 2021-06-11 11:10:10 +02:00
parent 9d7549e57b
commit 510d53e13b
7 changed files with 34 additions and 15 deletions

View File

@ -8,6 +8,7 @@ struct Entity {
int hb_y;
int hb_w;
int hb_h;
int layer;
color_t hb_color;
};
@ -15,8 +16,8 @@ struct Entity {
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, color_t hb_color);
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_grid_draw_hitboxes(void);
int entity_collide(void *restrict entity);
struct Entity *entity_collide(void *restrict entity, int mask);

9
include/layers.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
enum Layers {
L_NONE = 0,
L_SOLID = 1 << 1,
L_SEMISOLID = 1 << 2,
L_HARMFULL = 1 << 3,
L_PUSHABLE = 1 << 4,
};

View File

@ -1,32 +1,34 @@
#include "entity.h"
static int entity_collide_with(struct Entity *restrict,
struct Entity *restrict);
static int entity_collide_with(struct Entity *restrict, struct Entity *restrict,
int mask);
int
entity_collide(void *restrict entity)
struct Entity *
entity_collide(void *restrict entity, int mask)
{
struct Entity *const e = entity;
int i;
i = ENTITY_GRID_SIZE;
while (i-- > 0)
if (entity_collide_with(e, g_entity_grid[i]))
return 1;
if (entity_collide_with(e, g_entity_grid[i], mask))
return g_entity_grid[i];
return 0;
return NULL;
}
/* axis aligned bounding box collision checking */
static int
entity_collide_with(struct Entity *restrict self, struct Entity *restrict other)
entity_collide_with(struct Entity *restrict self, struct Entity *restrict other,
int mask)
{
const int sx = self->x + self->hb_x;
const int sy = self->y + self->hb_y;
const int ox = other->x + other->hb_x;
const int oy = other->y + other->hb_y;
if (self == NULL || other == NULL || self == other)
if (self == NULL || other == NULL || self == other ||
!(mask & other->layer))
return 0;
return sx < ox + other->hb_w && sx + self->hb_w > ox &&

View File

@ -1,11 +1,12 @@
#include "entity.h"
#include "layers.h"
#include <gint/display.h>
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, color_t hb_color)
int hb_h, int layer, color_t hb_color)
{
static int init_grid = 1;
struct Entity *const e = entity;
@ -16,6 +17,7 @@ entity_init(void *restrict entity, int x, int y, int hb_x, int hb_y, int hb_w,
e->hb_y = hb_y;
e->hb_w = hb_w;
e->hb_h = hb_h;
e->layer = layer;
e->hb_color = hb_color;
if (init_grid) {

View File

@ -1,4 +1,5 @@
#include "entity.h"
#include "layers.h"
#include "player.h"
#include "wall.h"
#include <gint/display.h>
@ -8,9 +9,11 @@ void
main(void)
{
struct Player player;
struct Player newb;
struct Wall walls[5];
player_init(&player, 16, 32);
player_init(&newb, 64, 128);
wall_init(&walls[0], 16, 0, DWIDTH - 32, 16);
wall_init(&walls[1], 16, DHEIGHT - 16, DWIDTH - 32, 16);
wall_init(&walls[2], 0, 0, 16, DHEIGHT);
@ -26,7 +29,7 @@ main(void)
clearevents();
player.x += keydown(KEY_RIGHT) - keydown(KEY_LEFT);
player.y += keydown(KEY_DOWN) - keydown(KEY_UP);
if (entity_collide(&player)) {
if (entity_collide(&player, L_SOLID) != NULL) {
player.x = previous_x;
player.y = previous_y;
}

View File

@ -1,10 +1,11 @@
#include "layers.h"
#include "player.h"
#include <gint/display.h>
void
player_init(struct Player *restrict p, int x, int y)
{
entity_init(p, x, y, 2, 2, 12, 12, C_BLUE);
entity_init(p, x, y, 2, 2, 12, 12, L_PUSHABLE, C_BLUE);
p->spd_x = 0.0;
p->spd_y = 0.0;
p->rem_x = 0.0;

View File

@ -1,8 +1,9 @@
#include "layers.h"
#include "wall.h"
#include <gint/display.h>
void
wall_init(struct Wall *restrict w, int x, int y, int width, int height)
{
entity_init(w, x, y, 0, 0, width, height, C_DARK);
entity_init(w, x, y, 0, 0, width, height, L_SOLID, C_DARK);
}