|
|
|
@ -51,9 +51,22 @@ static uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, boo
|
|
|
|
|
{
|
|
|
|
|
if (tile_x >= grid->width) return 0;
|
|
|
|
|
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
|
|
|
|
if (grid->tiles[tile_idx].solid == SOLID) return 1;
|
|
|
|
|
|
|
|
|
|
Vector2 overlap;
|
|
|
|
|
if (grid->tiles[tile_idx].solid == SOLID)
|
|
|
|
|
{
|
|
|
|
|
if (find_AABB_overlap(
|
|
|
|
|
(Vector2){ent->bbox.x, ent->bbox.y},
|
|
|
|
|
(Vector2){ent->bbox.width, ent->bbox.height},
|
|
|
|
|
(Vector2){tile_x * TILE_SIZE + grid->tiles[tile_idx].offset.x, tile_y * TILE_SIZE + grid->tiles[tile_idx].offset.y},
|
|
|
|
|
grid->tiles[tile_idx].size,
|
|
|
|
|
&overlap
|
|
|
|
|
))
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (check_oneway && grid->tiles[tile_idx].solid == ONE_WAY)
|
|
|
|
|
{
|
|
|
|
|
find_AABB_overlap(
|
|
|
|
@ -107,7 +120,16 @@ static uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid
|
|
|
|
|
{
|
|
|
|
|
if (tile_x >= grid->width) return 0;
|
|
|
|
|
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
|
|
|
|
if (grid->tiles[tile_idx].solid == SOLID) return 1;
|
|
|
|
|
if (grid->tiles[tile_idx].solid == SOLID)
|
|
|
|
|
{
|
|
|
|
|
Rectangle tile_rec = {
|
|
|
|
|
.x = tile_x * TILE_SIZE + grid->tiles[tile_idx].offset.x,
|
|
|
|
|
.y = tile_y * TILE_SIZE + grid->tiles[tile_idx].offset.y,
|
|
|
|
|
.width = grid->tiles[tile_idx].size.x,
|
|
|
|
|
.height = grid->tiles[tile_idx].size.y
|
|
|
|
|
};
|
|
|
|
|
if ( line_in_AABB(p1, p2, tile_rec) ) return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (check_oneway && grid->tiles[tile_idx].solid == ONE_WAY)
|
|
|
|
|
{
|
|
|
|
@ -241,7 +263,7 @@ static bool check_collision_and_move(
|
|
|
|
|
&& (p_ct->prev_position.y + p_bbox->size.y - 1 < other_pos->y))
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
//if (!check_collision_at(ent, p_ct->position, p_bbox->size, tilemap, offset))
|
|
|
|
|
//if (!check_collision_offset(ent, p_ct->position, p_bbox->size, tilemap, offset))
|
|
|
|
|
{
|
|
|
|
|
p_ct->position = Vector2Add(p_ct->position, offset);
|
|
|
|
|
}
|
|
|
|
@ -299,54 +321,67 @@ collision_end:
|
|
|
|
|
static uint8_t check_bbox_edges(
|
|
|
|
|
TileGrid_t* tilemap,
|
|
|
|
|
Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox,
|
|
|
|
|
int8_t len_reduction
|
|
|
|
|
bool ignore_fragile
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
uint8_t detected = 0;
|
|
|
|
|
|
|
|
|
|
bbox.x -= 2 * len_reduction;
|
|
|
|
|
bbox.y -= 2 * len_reduction;
|
|
|
|
|
|
|
|
|
|
CollideEntity_t ent =
|
|
|
|
|
{
|
|
|
|
|
.p_ent = p_ent,
|
|
|
|
|
.bbox = (Rectangle){pos.x - 1, pos.y + len_reduction, 1, bbox.y},
|
|
|
|
|
.bbox = (Rectangle){pos.x - 1, pos.y, 1, bbox.y},
|
|
|
|
|
.prev_bbox = (Rectangle){pos.x, pos.y, bbox.x, bbox.y},
|
|
|
|
|
.area = (TileArea_t){
|
|
|
|
|
.tile_x1 = (pos.x - 1) / TILE_SIZE,
|
|
|
|
|
.tile_y1 = (pos.y) / TILE_SIZE,
|
|
|
|
|
.tile_x2 = (pos.x - 1) / TILE_SIZE,
|
|
|
|
|
.tile_y2 = (pos.y + bbox.y - 1) / TILE_SIZE,
|
|
|
|
|
.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
|
|
|
|
.tile_x2 = (pos.x + bbox.x) / TILE_SIZE,
|
|
|
|
|
.tile_y2 = (pos.y + bbox.y) / TILE_SIZE,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Handle one-way platform
|
|
|
|
|
// Left
|
|
|
|
|
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 3;
|
|
|
|
|
uint8_t collide_type = check_collision_line(&ent, tilemap, false);
|
|
|
|
|
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
|
|
|
|
{
|
|
|
|
|
detected |= 1 << 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Right
|
|
|
|
|
ent.bbox.x = pos.x + bbox.x; // 2 to account for the previous subtraction
|
|
|
|
|
ent.area.tile_x1 = (pos.x + bbox.x) / TILE_SIZE;
|
|
|
|
|
ent.area.tile_x2 = ent.area.tile_x1;
|
|
|
|
|
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 2;
|
|
|
|
|
ent.bbox.x = pos.x + bbox.x + 1; // 2 to account for the previous subtraction
|
|
|
|
|
//ent.area.tile_x1 = (pos.x + bbox.x) / TILE_SIZE;
|
|
|
|
|
//ent.area.tile_x2 = ent.area.tile_x1;
|
|
|
|
|
collide_type = check_collision_line(&ent, tilemap, false);
|
|
|
|
|
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
|
|
|
|
{
|
|
|
|
|
detected |= 1 << 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Up
|
|
|
|
|
ent.bbox.x = pos.x + len_reduction;
|
|
|
|
|
ent.bbox.x = pos.x;
|
|
|
|
|
ent.bbox.y = pos.y - 1;
|
|
|
|
|
ent.bbox.width = bbox.x;
|
|
|
|
|
ent.bbox.height = 1;
|
|
|
|
|
ent.area.tile_x1 = (pos.x) / TILE_SIZE,
|
|
|
|
|
ent.area.tile_x2 = (pos.x + bbox.x - 1) / TILE_SIZE,
|
|
|
|
|
ent.area.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
|
|
|
|
ent.area.tile_y2 = ent.area.tile_y1;
|
|
|
|
|
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 1;
|
|
|
|
|
//ent.area.tile_x1 = (pos.x) / TILE_SIZE,
|
|
|
|
|
//ent.area.tile_x2 = (pos.x + bbox.x - 1) / TILE_SIZE,
|
|
|
|
|
//ent.area.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
|
|
|
|
//ent.area.tile_y2 = ent.area.tile_y1;
|
|
|
|
|
collide_type = check_collision_line(&ent, tilemap, false);
|
|
|
|
|
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
|
|
|
|
{
|
|
|
|
|
detected |= 1 << 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Down
|
|
|
|
|
ent.bbox.y = pos.y + bbox.y;
|
|
|
|
|
ent.area.tile_y1 = (pos.y + bbox.y) / TILE_SIZE,
|
|
|
|
|
ent.area.tile_y2 = ent.area.tile_y1;
|
|
|
|
|
detected |= (check_collision_line(&ent, tilemap, true) ? 1 : 0);
|
|
|
|
|
ent.bbox.y = pos.y + bbox.y + 1;
|
|
|
|
|
//ent.area.tile_y1 = (pos.y + bbox.y) / TILE_SIZE,
|
|
|
|
|
//ent.area.tile_y2 = ent.area.tile_y1;
|
|
|
|
|
collide_type = check_collision_line(&ent, tilemap, false);
|
|
|
|
|
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
|
|
|
|
{
|
|
|
|
|
detected |= 1;
|
|
|
|
|
}
|
|
|
|
|
return detected;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -686,7 +721,7 @@ void player_crushing_system(Scene_t* scene)
|
|
|
|
|
|
|
|
|
|
uint8_t edges = check_bbox_edges(
|
|
|
|
|
&data->tilemap, p_player,
|
|
|
|
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 2
|
|
|
|
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, true
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if ((edges & 0b1100) == 0b1100 || (edges & 0b0011) == 0b0011)
|
|
|
|
@ -807,7 +842,7 @@ void tile_collision_system(Scene_t* scene)
|
|
|
|
|
// Post movement edge check to zero out velocity
|
|
|
|
|
uint8_t edges = check_bbox_edges(
|
|
|
|
|
&data->tilemap, p_ent,
|
|
|
|
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 0
|
|
|
|
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, false
|
|
|
|
|
);
|
|
|
|
|
if (edges & (1<<3))
|
|
|
|
|
{
|
|
|
|
@ -933,7 +968,7 @@ void global_external_forces_system(Scene_t* scene)
|
|
|
|
|
// Zero out acceleration for contacts with sturdy entites and tiles
|
|
|
|
|
uint8_t edges = check_bbox_edges(
|
|
|
|
|
&data->tilemap, p_ent,
|
|
|
|
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 0
|
|
|
|
|
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, false
|
|
|
|
|
);
|
|
|
|
|
if (edges & (1<<3))
|
|
|
|
|
{
|
|
|
|
|