Tile and bitmask system base

This commit is contained in:
KikooDX 2021-01-04 18:02:11 +01:00
parent 8011f9d126
commit f8c6953803
9 changed files with 77 additions and 31 deletions

View File

@ -6,10 +6,12 @@
#include "conf.h"
#include "level.h"
#include "tiles.h"
/* Return tile at the given position.
* 0 is out of bound or empty. */
uint8_t collide_point(Vec point, const Level *level, uint layer);
bool player_collide(Player *player, Vec position, const Level *level, uint layer_id);
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);
#endif /* _DEF_PLAYER_COLLIDE */

View File

@ -3,10 +3,12 @@
#include <gint/defs/types.h>
#include "tiles.h"
typedef struct Level {
uint width; /* in tiles */
uint height; /* in tiles */
const uint8_t **layers; /* points toward the level content */
const Tile **layers; /* points toward the level content */
uint8_t layers_count;
uint8_t solid_layer; /* id of the solid layer */
} Level;

21
include/tiles.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _DEF_TILES
#define _DEF_TILES
typedef unsigned char Tile; /* the tile ID */
typedef unsigned char Tile_flags; /* the tile properties (bitmask) */
/* define flags */
#define F_VISIBLE 0b1
#define F_SOLID 0b10
/* define properties */
#define P_AIR (0)
#define P_BASE (F_VISIBLE | F_SOLID)
#define P_UNKNOWN (F_VISIBLE)
enum {
ID_AIR,
ID_BASE,
};
Tile_flags tile_get_flags(Tile tile);
#endif /* _DEF_TILES */

View File

@ -1,5 +1,5 @@
#ifndef _DEF_VEC
#define _DEF_VEC
#ifndef _DEF_TILE_PROPS
#define _DEF_TILE_PROPS
typedef struct {
int x;
@ -33,4 +33,4 @@ void vec_clamp(Vec *to_limit, Vec min, Vec max);
/* Draw a rectangle using two Vec as coordinates */
void vec_drect(Vec top_left, Vec bottom_right, int color);
#endif /* _DEF_VEC */
#endif /* _DEF_TILE_PROPS */

View File

@ -2,6 +2,7 @@
local function create_includes_c()
io.write[[#include "level.h"
#include "tiles.h"
]]
end
@ -40,7 +41,7 @@ local function create_structure_c(id)
if content then
-- layers
for i, layer in ipairs(content.layers) do
io.write("const uint8_t tiles_", id, "_", i, "[] = {\n\t")
io.write("const Tile tiles_", id, "_", i, "[] = {\n\t")
for i, v in ipairs(layer) do
io.write(v, ", ")
if i % 14 == 0 and i ~= #layer then
@ -50,7 +51,7 @@ local function create_structure_c(id)
io.write("\n};\n");
end
-- array
io.write("const uint8_t *layers_", id, "[] = {")
io.write("const Tile *layers_", id, "[] = {")
for i = 1, #content.layers, 1 do
io.write("tiles_", id, "_", i, ", ")
end

View File

@ -4,8 +4,9 @@
#include "collide.h"
#include "conf.h"
#include "level.h"
#include "tiles.h"
uint8_t collide_point(Vec point, const Level *level, uint layer_id) {
Tile_flags collide_point(Vec point, const Level *level, uint layer_id) {
Vec cursor; /* the final position to test */
vec_cpy(&cursor, point);
vec_div(&cursor, TILE_SIZE); /* get the expected tile ID */
@ -14,27 +15,35 @@ uint8_t collide_point(Vec point, const Level *level, uint layer_id) {
return 0; /* the point is out of bounds */
}
else {
return level->layers[layer_id][cursor.x + cursor.y * level->width];
const Tile tile_id = level->layers[layer_id][cursor.x + cursor.y * level->width];
return tile_get_flags(tile_id);
}
}
bool player_collide(Player *player, Vec position, const Level *level, uint layer_id) {
Tile_flags player_collide_or(Player *player, Vec position, const Level *level, uint layer_id) {
Vec pos;
vec_cpy(&pos, position);
if (collide_point(pos, level, layer_id)) {
return true;
}
Tile_flags flags = 0;
flags |= collide_point(pos, level, layer_id);
pos.x += player->hbox.x;
if (collide_point(pos, level, layer_id)) {
return true;
}
flags |= collide_point(pos, level, layer_id);
pos.y += player->hbox.y;
if (collide_point(pos, level, layer_id)) {
return true;
}
flags |= collide_point(pos, level, layer_id);
pos.x -= player->hbox.x;
if (collide_point(pos, level, layer_id)) {
return true;
}
return false;
flags |= collide_point(pos, level, layer_id);
return flags;
}
Tile_flags player_collide_and(Player *player, Vec position, const Level *level, uint layer_id) {
Vec pos;
vec_cpy(&pos, position);
Tile_flags flags = -1;
flags &= collide_point(pos, level, layer_id);
pos.x += player->hbox.x;
flags &= collide_point(pos, level, layer_id);
pos.y += player->hbox.y;
flags &= collide_point(pos, level, layer_id);
pos.x -= player->hbox.x;
flags &= collide_point(pos, level, layer_id);
return flags;
}

View File

@ -3,6 +3,7 @@
#include "conf.h"
#include "level.h"
#include "camera.h"
#include "tiles.h"
#define VEC_PRECISE_HALF_DISP (Vec){DWIDTH * VEC_PRECISION / (2 * SCALE), DHEIGHT * VEC_PRECISION / (2 * SCALE)}
@ -16,7 +17,7 @@ void level_draw(const Level *level, Camera *camera) {
}
void layer_draw(const Level *level, Camera *camera, uint layer_id) {
const uint8_t *layer = level->layers[layer_id];
const Tile *layer = level->layers[layer_id];
Vec display_tl, display_br;
vec_cpy(&display_tl, camera->pos);
vec_cpy(&display_br, display_tl);
@ -30,7 +31,7 @@ void layer_draw(const Level *level, Camera *camera, uint layer_id) {
int end_y = (display_br.y < level->height) ? display_br.y + 1 : level->height;
for (int y = start_y; y < end_y; ++y) {
for (int x = start_x; x < end_x; ++x) {
const uint8_t cell = layer[x + y * level->width];
const Tile cell = layer[x + y * level->width];
#ifdef FX9860G
const int color = C_LIGHT;
#endif /* FX9860G */

View File

@ -7,6 +7,7 @@
#include "camera.h"
#include "input.h"
#include "collide.h"
#include "tiles.h"
/* TODO: Determine FRICTION and ACCELERATION from UPS. */
#define MAX_SPD (128 * PXS)
@ -17,7 +18,7 @@
#define GRACE_UNITS (int)(UPS / 5)
#define EARLY_UNITS (int)(UPS / 5)
#define SGN(x) ((x > 0) ? (1) : ((x < 0) ? (-1) : (0)))
#define PLAYER_COLLIDE(pos) player_collide(player, pos, level, level->solid_layer)
#define PLAYER_COLLIDE_SOLID(pos) (player_collide_or(player, pos, level, level->solid_layer) & F_SOLID)
void player_move(Player *player, const Level *level) {
/* TODO: Take into account player's hitbox */
@ -27,11 +28,11 @@ void player_move(Player *player, const Level *level) {
vec_cpy(&destination, player->pos);
/* snap the player to the grid if they hit a wall */
destination.x += player->spd.x;
if (PLAYER_COLLIDE(destination)) {
if (PLAYER_COLLIDE_SOLID(destination)) {
destination.x = player->pos.x - player->pos.x % TILE_SIZE;
/* Move the player tile per tile until it enters an
* occuped tile. */
while (!PLAYER_COLLIDE(destination)) {
while (!PLAYER_COLLIDE_SOLID(destination)) {
destination.x += TILE_SIZE * sgn_spd_x;
}
/* then, move it back one tile */
@ -40,9 +41,9 @@ void player_move(Player *player, const Level *level) {
}
/* do the same for y */
destination.y += player->spd.y;
if (PLAYER_COLLIDE(destination)) {
if (PLAYER_COLLIDE_SOLID(destination)) {
destination.y = player->pos.y - player->pos.y % TILE_SIZE;
while (!PLAYER_COLLIDE(destination)) {
while (!PLAYER_COLLIDE_SOLID(destination)) {
destination.y += TILE_SIZE * sgn_spd_y;
}
destination.y -= TILE_SIZE * sgn_spd_y;

9
src/tiles.c Normal file
View File

@ -0,0 +1,9 @@
#include "tiles.h"
Tile_flags tile_get_flags(Tile tile) {
switch (tile) {
case ID_AIR: return P_AIR; break;
case ID_BASE: return P_BASE; break;
default: return P_UNKNOWN; break;
}
}