From 1844b66e09882d7e0ae1828fe76b8272483ac318 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Tue, 5 Jan 2021 16:24:55 +0100 Subject: [PATCH] Simplified a bit and cleaned up collision code --- include/collide.h | 10 +++++----- include/player.h | 2 +- src/collide.c | 36 ++++++++++++++++++++++-------------- src/player.c | 6 +++--- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/include/collide.h b/include/collide.h index 48099df..46f110e 100644 --- a/include/collide.h +++ b/include/collide.h @@ -8,10 +8,10 @@ #include "level.h" #include "tiles.h" -/* Return tile at the given position. - * 0 is out of bound or empty. */ -Tile collide_point(Vec point, const Level *level, uint layer); -Tile_flags player_collide_or(Player *player, Vec position, const Level *level, uint layer_id); -Tile_flags player_collide_and(Player *player, Vec position, const Level *level, uint layer_id); +/* Return tile flags at the given position. + * P_AIR is out of bound or empty. */ +Tile collide_point(Vec point, const Level *level); +Tile_flags player_collide_or(Player *player, Vec position, const Level *level); +Tile_flags player_collide_and(Player *player, Vec position, const Level *level); #endif /* _DEF_PLAYER_COLLIDE */ diff --git a/include/player.h b/include/player.h index 03012c3..a5a30b3 100644 --- a/include/player.h +++ b/include/player.h @@ -22,6 +22,6 @@ typedef struct Player { void player_move(Player *player, const Level *level); void player_step(Player *player, Input *input, const Level *level, uint step); void player_draw(Player *player, Camera *camera); -void player_draw_debug(Player *player, uint step, const Level *level, uint layer_id); +void player_draw_debug(Player *player, uint step, const Level *level); #endif /* _DEF_PLAYER */ diff --git a/src/collide.c b/src/collide.c index bd212f6..84e862d 100644 --- a/src/collide.c +++ b/src/collide.c @@ -6,44 +6,52 @@ #include "level.h" #include "tiles.h" -Tile_flags collide_point(Vec point, const Level *level, uint layer_id) { +Tile_flags collide_point(Vec point, const Level *level) { Vec cursor; /* the final position to test */ vec_cpy(&cursor, point); vec_div(&cursor, TILE_SIZE); /* get the expected tile ID */ if (point.x < 0 || point.y < 0 || cursor.x >= level->width || cursor.y >= level->height) { - return 0; /* the point is out of bounds */ + return P_AIR; /* the point is out of bounds */ } else { - const Tile tile_id = level->layers[layer_id][cursor.x + cursor.y * level->width]; + const Tile tile_id = level->layers[level->solid_layer][cursor.x + cursor.y * level->width]; return tile_get_flags(tile_id); } } -Tile_flags player_collide_or(Player *player, Vec position, const Level *level, uint layer_id) { +Tile_flags player_collide_or(Player *player, Vec position, const Level *level) { Vec pos; vec_cpy(&pos, position); Tile_flags flags = 0; - flags |= collide_point(pos, level, layer_id); + flags |= collide_point(pos, level); pos.x += player->hbox.x; - flags |= collide_point(pos, level, layer_id); + flags |= collide_point(pos, level); pos.y += player->hbox.y; - flags |= collide_point(pos, level, layer_id); + flags |= collide_point(pos, level); pos.x -= player->hbox.x; - flags |= collide_point(pos, level, layer_id); + flags |= collide_point(pos, level); return flags; } -Tile_flags player_collide_and(Player *player, Vec position, const Level *level, uint layer_id) { +Tile_flags player_collide_and(Player *player, Vec position, const Level *level) { + /* DRY, get the collision flags and do &= on flags if there is + * any. */ + void process_flags(Player *player, const Level *level, Vec pos, Tile_flags *flags) { + Tile tile_flags = collide_point(pos, level); + if (tile_flags) { + *flags &= tile_flags; + } + } Vec pos; vec_cpy(&pos, position); - Tile_flags flags = -1; - flags &= collide_point(pos, level, layer_id); + Tile_flags flags = -1; /* since unsigned, max value */ + process_flags(player, level, pos, &flags); pos.x += player->hbox.x; - flags &= collide_point(pos, level, layer_id); + process_flags(player, level, pos, &flags); pos.y += player->hbox.y; - flags &= collide_point(pos, level, layer_id); + process_flags(player, level, pos, &flags); pos.x -= player->hbox.x; - flags &= collide_point(pos, level, layer_id); + process_flags(player, level, pos, &flags); return flags; } diff --git a/src/player.c b/src/player.c index 5c7a035..cd448be 100644 --- a/src/player.c +++ b/src/player.c @@ -21,7 +21,7 @@ #define H_CLIP_MARGIN (TILE_SIZE / 4) #define V_CLIP_MARGIN (TILE_SIZE / 3) #define SGN(x) (((x) > 0) ? (1) : (((x) < 0) ? (-1) : (0))) -#define PLAYER_COLLIDE_SOLID(pos) (player_collide_or(player, pos, level, level->solid_layer) & F_SOLID) +#define PLAYER_COLLIDE_SOLID(pos) (player_collide_or(player, pos, level) & F_SOLID) void player_move(Player *player, const Level *level) { /* TODO: Take into account player's hitbox */ @@ -131,7 +131,7 @@ void player_draw(Player *player, Camera *camera) { vec_drect(tl, br, C_BLACK); } -void player_draw_debug(Player *player, uint step, const Level *level, uint layer_id) { +void player_draw_debug(Player *player, uint step, const Level *level) { /* This debug function displays more or less usefull * informations for debugging player movement. */ dprint(0, 0, C_BLACK, "x: %d", player->pos.x); @@ -140,6 +140,6 @@ void player_draw_debug(Player *player, uint step, const Level *level, uint layer dprint(0, 30, C_BLACK, "st: %u", step); dprint(0, 40, C_BLACK, "cx: %d", player->pos.x / TILE_SIZE); dprint(0, 50, C_BLACK, "cy: %d", player->pos.y / TILE_SIZE); - dprint(0, 60, C_BLACK, "cl: %d", collide_point(player->pos, level, layer_id)); + dprint(0, 60, C_BLACK, "cl: %d", collide_point(player->pos, level)); }