forked from kdx/jtmm2-old
Simplified a bit and cleaned up collision code
This commit is contained in:
parent
8804a12a90
commit
1844b66e09
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue