Tile and bitmask system base
This commit is contained in:
parent
8011f9d126
commit
f8c6953803
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
11
src/player.c
11
src/player.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Reference in New Issue