#include #include #include "collide.h" #include "conf.h" #include "level.h" #include "tiles.h" 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 P_AIR; /* the point is out of bounds */ } else { 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) { Vec pos; vec_cpy(&pos, position); Tile_flags flags = 0; flags |= collide_point(pos, level); pos.x += player->hbox.x; flags |= collide_point(pos, level); pos.y += player->hbox.y; flags |= collide_point(pos, level); pos.x -= player->hbox.x; flags |= collide_point(pos, level); return flags; } 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; /* since unsigned, max value */ process_flags(player, level, pos, &flags); pos.x += player->hbox.x; process_flags(player, level, pos, &flags); pos.y += player->hbox.y; process_flags(player, level, pos, &flags); pos.x -= player->hbox.x; process_flags(player, level, pos, &flags); return flags; }