Meh collision system, good enough for now. Can be "playtested"

This commit is contained in:
KikooDX 2020-09-28 12:53:04 +02:00
parent f8bb34e4c1
commit 01c8782e8c
9 changed files with 109 additions and 13 deletions

View File

@ -2,6 +2,7 @@
#define _DEF_PLAYER_COLLIDE
#include <gint/defs/types.h>
#include <stdbool.h>
#include "conf.h"
#include "level.h"
@ -9,5 +10,10 @@
/* return tile at the given position
* -1 is out of bound */
uint8_t collide_point(Vec point, const Level *level, uint layer);
_Bool collide_right(Player *player, Vec position, const Level *level, uint layer_id);
_Bool collide_left(Player *player, Vec position, const Level *level, uint layer_id);
_Bool collide_down(Player *player, Vec position, const Level *level, uint layer_id);
_Bool collide_up(Player *player, Vec position, const Level *level, uint layer_id);
_Bool collide_full(Player *player, Vec position, const Level *level, uint layer_id);
#endif /* _DEF_PLAYER_COLLIDE */

View File

@ -1 +1 @@
#define DEBUG
//#define DEBUG

View File

@ -9,6 +9,7 @@ typedef struct Level
int height; /* in tiles */
const uint8_t **layers; /* points toward the level content */
int layers_count;
uint solid_layer; /* id of the solid layer */
} Level;
#include "camera.h"

View File

@ -15,7 +15,7 @@ typedef struct Player
#include "camera.h"
#include "input.h"
void player_step(Player *player, Input *input);
void player_step(Player *player, Input *input, const Level *level);
void player_draw(Player *player, Camera *camera);
void player_draw_debug(Player *player, uint step, const Level *level, uint layer_id);

View File

@ -1,11 +1,12 @@
#!/usr/bin/env luajit
math.randomseed(os.time()) --set randomseed
local function create_random_level(width, height, layers)
io.write(width, "\n")
io.write(height, "\n")
for i = 1, layers, 1 do
for r = 1, width * height, 1 do
io.write(math.floor(math.random() * 2)) --random 0 or 1
io.write(math.floor(math.random() * 2)) --random 0 (2/3) or 1 (1/3)
io.write("\n")
end
if i ~= layers then
@ -14,4 +15,4 @@ local function create_random_level(width, height, layers)
end
end
create_random_level(10, 4, 1)
create_random_level(64, 64, 1)

View File

@ -60,7 +60,8 @@ local function create_structure_c(id)
io.write("\t.width = ", content.width, ",\n")
io.write("\t.height = ", content.height, ",\n")
io.write("\t.layers = layers_", id, ",\n")
io.write("\t.layers_count = ", #content.layers, "\n")
io.write("\t.layers_count = ", #content.layers, ",\n")
io.write("\t.solid_layer = 0\n")
io.write("};\n")
end
end

View File

@ -1,4 +1,5 @@
#include <gint/defs/types.h>
#include <stdbool.h>
#include "collide.h"
#include "conf.h"
@ -12,10 +13,86 @@ uint8_t collide_point(Vec point, const Level *level, uint layer_id)
if (point.x < 0 || point.y < 0 ||
cursor.x >= level->width || cursor.y >= level->height)
{
return -1; /* the point is out of bounds */
return 0; /* the point is out of bounds */
}
else
{
return level->layers[layer_id][cursor.x + cursor.y * level->width];
}
}
_Bool collide_right(Player *player, Vec position, const Level *level, uint layer_id)
{
Vec pos;
vec_cpy(&pos, position);
vec_sub(&pos, player->origin);
pos.x += player->hbox.x;
if (collide_point(pos, level, layer_id))
{
return true;
}
pos.y += player->hbox.y;
if (collide_point(pos, level, layer_id))
{
return true;
}
return false;
}
_Bool collide_left(Player *player, Vec position, const Level *level, uint layer_id)
{
Vec pos;
vec_cpy(&pos, position);
vec_sub(&pos, player->origin);
if (collide_point(pos, level, layer_id))
{
return true;
}
pos.y += player->hbox.y;
if (collide_point(pos, level, layer_id))
{
return true;
}
return false;
}
_Bool collide_down(Player *player, Vec position, const Level *level, uint layer_id)
{
Vec pos;
vec_cpy(&pos, position);
vec_sub(&pos, player->origin);
pos.y += player->hbox.y;
if (collide_point(pos, level, layer_id))
{
return true;
}
pos.x += player->hbox.x;
if (collide_point(pos, level, layer_id))
{
return true;
}
return false;
}
_Bool collide_up(Player *player, Vec position, const Level *level, uint layer_id)
{
Vec pos;
vec_cpy(&pos, position);
vec_sub(&pos, player->origin);
if (collide_point(pos, level, layer_id))
{
return true;
}
pos.x += player->hbox.x;
if (collide_point(pos, level, layer_id))
{
return true;
}
return false;
}
_Bool collide_full(Player *player, Vec position, const Level *level, uint layer_id)
{
return collide_up(player, position, level, layer_id) ||
collide_down(player, position, level, layer_id);
}

View File

@ -31,11 +31,12 @@ int play_level(uint level_id)
{
/* create player */
Player player = {
.pos = {TILE_SIZE, TILE_SIZE},
.hbox = {7 * VEC_PRECISION, 7 * VEC_PRECISION},
.vbox = {7, 7},
//.pos = {TILE_SIZE, TILE_SIZE},
.hbox = {7 * VEC_PRECISION - 1, 7 * VEC_PRECISION - 1},
.vbox = {6, 6},
.origin = {4 * VEC_PRECISION, 4 * VEC_PRECISION}
};
vec_cpy(&player.pos, player.origin); /* place the player at "0/0"
/* set level */
const Level *level;
@ -88,7 +89,7 @@ void step_event(Player *player, const Level *level, Camera *camera, Input *input
{
//getkey();
input_step(input);
player_step(player, input);
player_step(player, input, level);
level_step(level);
camera_step(camera);
}

View File

@ -6,14 +6,21 @@
#include "input.h"
#include "collide.h"
void player_step(Player *player, Input *input)
void player_step(Player *player, Input *input, const Level *level)
{
Vec move = {
(input_is_down(input, K_RIGHT) - input_is_down(input, K_LEFT)),
(input_is_down(input, K_DOWN) - input_is_down(input, K_UP))
};
vec_mul(&move, 32 * PXS);
vec_add(&player->pos, move);
vec_mul(&move, 32 * PXS); /* set speed */
Vec destination;
vec_cpy(&destination, player->pos);
vec_add(&destination, move);
if (collide_full(player, player->pos, level, level->solid_layer) ||
!collide_full(player, destination, level, level->solid_layer))
{
vec_cpy(&player->pos, destination);
}
}
void player_draw(Player *player, Camera *camera)
@ -30,6 +37,7 @@ void player_draw(Player *player, Camera *camera)
vec_sub(&br, camera->offset);
vec_mul(&tl, SCALE);
vec_mul(&br, SCALE);
vec_add(&br, (Vec){SCALE - 1, SCALE - 1});
vec_drect(tl, br, C_BLACK);
}
@ -43,3 +51,4 @@ void player_draw_debug(Player *player, uint step, const Level *level, uint layer
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));
}