Entity collision

main
Cameron Murphy Reikes 2 years ago
parent fadae61b2b
commit 8c24344dc9

@ -105,7 +105,7 @@ typedef struct Entity
#define LEVEL_TILES 60 #define LEVEL_TILES 60
#define TILE_SIZE 32 // in pixels #define TILE_SIZE 32 // in pixels
#define MAX_ENTITIES 128 #define MAX_ENTITIES 128
#define PLAYER_SPEED 3.0f // in meters per second #define PLAYER_SPEED 3.5f // in meters per second
#define PLAYER_ROLL_SPEED 7.0f #define PLAYER_ROLL_SPEED 7.0f
typedef struct Level typedef struct Level
{ {
@ -170,6 +170,23 @@ char *tprint(const char *format, ...)
return to_return; return to_return;
} }
Vec2 entity_aabb_size(Entity *e)
{
if(e->kind == ENTITY_PLAYER)
{
return V2(TILE_SIZE, TILE_SIZE);
}
else if(e->kind == ENTITY_OLD_MAN)
{
return V2(TILE_SIZE*0.5f, TILE_SIZE*0.5f);
}
else
{
assert(false);
return (Vec2){0};
}
}
// tilecoord is integer tile position, not like tile coord // tilecoord is integer tile position, not like tile coord
Vec2 tilecoord_to_world(TileCoord t) Vec2 tilecoord_to_world(TileCoord t)
{ {
@ -858,12 +875,18 @@ void line(Vec2 from, Vec2 to, float line_width, Color color)
void dbgline(Vec2 from, Vec2 to) void dbgline(Vec2 from, Vec2 to)
{ {
#ifdef DEVTOOLS
line(from, to, 2.0f, RED); line(from, to, 2.0f, RED);
#else
(void)from;
(void)to;
#endif
} }
// in world space // in world space
void dbgrect(AABB rect) void dbgrect(AABB rect)
{ {
#ifdef DEVTOOLS
const float line_width = 0.5; const float line_width = 0.5;
const Color col = RED; const Color col = RED;
Quad q = quad_aabb(rect); Quad q = quad_aabb(rect);
@ -871,13 +894,23 @@ void dbgrect(AABB rect)
line(q.ur, q.lr, line_width, col); line(q.ur, q.lr, line_width, col);
line(q.lr, q.ll, line_width, col); line(q.lr, q.ll, line_width, col);
line(q.ll, q.ul, line_width, col); line(q.ll, q.ul, line_width, col);
#else
(void)rect;
#endif
} }
// returns new pos after moving and sliding against collidable things // returns new pos after moving and sliding against collidable things
Vec2 move_and_slide(Vec2 position, Vec2 movement_this_frame, Vec2 collision_aabb_size) Vec2 move_and_slide(Entity *from, Vec2 position, Vec2 movement_this_frame)
{ {
Vec2 collision_aabb_size = entity_aabb_size(from);
Vec2 new_pos = AddV2(position, movement_this_frame); Vec2 new_pos = AddV2(position, movement_this_frame);
AABB at_new = centered_aabb(new_pos, collision_aabb_size); AABB at_new = centered_aabb(new_pos, collision_aabb_size);
dbgrect(at_new);
AABB to_check[64] = {0};
int to_check_index = 0;
// add tilemap boxes
{
Vec2 at_new_size_vector = SubV2(at_new.lower_right, at_new.upper_left); Vec2 at_new_size_vector = SubV2(at_new.lower_right, at_new.upper_left);
Vec2 points_to_check[] = { Vec2 points_to_check[] = {
AddV2(at_new.upper_left, V2(0.0, 0.0)), AddV2(at_new.upper_left, V2(0.0, 0.0)),
@ -885,22 +918,37 @@ Vec2 move_and_slide(Vec2 position, Vec2 movement_this_frame, Vec2 collision_aabb
AddV2(at_new.upper_left, V2(at_new_size_vector.X, at_new_size_vector.Y)), AddV2(at_new.upper_left, V2(at_new_size_vector.X, at_new_size_vector.Y)),
AddV2(at_new.upper_left, V2(0.0, at_new_size_vector.Y)), AddV2(at_new.upper_left, V2(0.0, at_new_size_vector.Y)),
}; };
//dbgsquare(position); for(int i = 0; i < ARRLEN(points_to_check); i++)
//dbgsquare(at_new.upper_left);
//dbgsquare(at_new.lower_right);
for(int i = 0; i < sizeof(points_to_check)/sizeof(*points_to_check); i++)
{ {
Vec2 *it = &points_to_check[i]; Vec2 *it = &points_to_check[i];
TileCoord to_check = world_to_tilecoord(*it); TileCoord tilecoord_to_check = world_to_tilecoord(*it);
uint16_t tile_id = get_tile(&level_level0, to_check).kind; uint16_t tile_id = get_tile(&level_level0, tilecoord_to_check).kind;
if(tile_id == 53 || tile_id == 0 || tile_id == 367 || tile_id == 317 || tile_id == 313 || tile_id == 366 || tile_id == 368) if(tile_id == 53 || tile_id == 0 || tile_id == 367 || tile_id == 317 || tile_id == 313 || tile_id == 366 || tile_id == 368)
{ {
dbgsquare(tilecoord_to_world(to_check)); to_check[to_check_index++] = tile_aabb(tilecoord_to_check);
AABB to_depenetrate_from = tile_aabb(to_check); assert(to_check_index < ARRLEN(to_check));
while(overlapping(to_depenetrate_from, at_new)) }
}
}
// add entity boxes
if(!(from->kind == ENTITY_PLAYER && from->is_rolling))
{
for(int i = 0; i < ARRLEN(entities); i++) if(entities[i].exists)
{ {
//while(false) if(&entities[i] != from)
{
to_check[to_check_index++] = centered_aabb(entities[i].pos, entity_aabb_size(&entities[i]));
}
}
}
for(int i = 0; i < to_check_index; i++)
{
AABB to_depenetrate_from = to_check[i];
dbgrect(to_depenetrate_from);
while(overlapping(to_depenetrate_from, at_new))
{ {
//dbgsquare(to_depenetrate_from.upper_left); //dbgsquare(to_depenetrate_from.upper_left);
//dbgsquare(to_depenetrate_from.lower_right); //dbgsquare(to_depenetrate_from.lower_right);
@ -930,8 +978,6 @@ Vec2 move_and_slide(Vec2 position, Vec2 movement_this_frame, Vec2 collision_aabb
at_new.lower_right = AddV2(at_new.lower_right,move); at_new.lower_right = AddV2(at_new.lower_right,move);
} }
} }
}
}
return aabb_center(at_new); return aabb_center(at_new);
} }
@ -1114,7 +1160,7 @@ void frame(void)
{ {
if(player->speed <= 0.01f) player->speed = PLAYER_SPEED; if(player->speed <= 0.01f) player->speed = PLAYER_SPEED;
player->speed = Lerp(player->speed, dt * 3.0f, PLAYER_SPEED); player->speed = Lerp(player->speed, dt * 3.0f, PLAYER_SPEED);
player->pos = move_and_slide(player->pos, MulV2F(movement, dt * pixels_per_meter * player->speed), V2(TILE_SIZE, TILE_SIZE)); player->pos = move_and_slide(player, player->pos, MulV2F(movement, dt * pixels_per_meter * player->speed));
if(player->is_rolling) if(player->is_rolling)
{ {
draw_animated_sprite(&knight_rolling, player->roll_progress, player->facing_left, character_sprite_pos, WHITE); draw_animated_sprite(&knight_rolling, player->roll_progress, player->facing_left, character_sprite_pos, WHITE);

Loading…
Cancel
Save