This commit is contained in:
KikooDX 2021-01-06 18:43:06 +01:00
commit 70e2291348
4 changed files with 31 additions and 23 deletions

View File

@ -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 */

View File

@ -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 */

View File

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

View File

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