Compare commits
3 Commits
5267c318f2
...
3ee14d5f47
Author | SHA1 | Date |
---|---|---|
|
3ee14d5f47 | |
|
0f5a347cec | |
|
bb4a9a8f3c |
|
@ -58,12 +58,14 @@ bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box)
|
||||||
|
|
||||||
Vector2 corners[3] =
|
Vector2 corners[3] =
|
||||||
{
|
{
|
||||||
{box.x + box.width - 1, box.y},
|
{box.x + box.width, box.y},
|
||||||
{box.x + box.width - 1, box.y + box.height - 1},
|
{box.x + box.width, box.y + box.height},
|
||||||
{box.x, box.y + box.height - 1},
|
{box.x, box.y + box.height},
|
||||||
};
|
};
|
||||||
|
|
||||||
float F = (A * box.x + B * box.y + C);
|
float F = (A * box.x + B * box.y + C);
|
||||||
|
|
||||||
|
bool collide = false;
|
||||||
uint8_t last_mode = 0;
|
uint8_t last_mode = 0;
|
||||||
if (fabs(F) < 1e-3)
|
if (fabs(F) < 1e-3)
|
||||||
{
|
{
|
||||||
|
@ -86,8 +88,29 @@ bool line_in_AABB(Vector2 p1, Vector2 p2, Rectangle box)
|
||||||
{
|
{
|
||||||
mode = (F > 0) ? 1 : 2;
|
mode = (F > 0) ? 1 : 2;
|
||||||
}
|
}
|
||||||
if (mode != last_mode) return true;
|
if (mode != last_mode)
|
||||||
|
{
|
||||||
|
collide = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
last_mode = mode;
|
last_mode = mode;
|
||||||
}
|
}
|
||||||
return false;
|
if (!collide) return false;
|
||||||
|
|
||||||
|
//Projection check
|
||||||
|
Vector2 overlap = {0};
|
||||||
|
Vector2 l1, l2;
|
||||||
|
l1.x = p1.x;
|
||||||
|
l1.y = p2.x;
|
||||||
|
l2.x = box.x;
|
||||||
|
l2.y = box.x + box.width;
|
||||||
|
|
||||||
|
find_1D_overlap(l1, l2, &overlap.x);
|
||||||
|
l1.x = p1.y;
|
||||||
|
l1.y = p2.y;
|
||||||
|
l2.x = box.y;
|
||||||
|
l2.y = box.y + box.height;
|
||||||
|
find_1D_overlap(l1, l2, &overlap.y);
|
||||||
|
|
||||||
|
return (overlap.x != 0 && overlap.y != 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,22 @@ static uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, boo
|
||||||
{
|
{
|
||||||
if (tile_x >= grid->width) return 0;
|
if (tile_x >= grid->width) return 0;
|
||||||
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
||||||
if (grid->tiles[tile_idx].solid == SOLID) return 1;
|
|
||||||
|
|
||||||
Vector2 overlap;
|
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)
|
if (check_oneway && grid->tiles[tile_idx].solid == ONE_WAY)
|
||||||
{
|
{
|
||||||
find_AABB_overlap(
|
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;
|
if (tile_x >= grid->width) return 0;
|
||||||
unsigned int tile_idx = tile_y*grid->width + tile_x;
|
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)
|
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))
|
&& (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);
|
p_ct->position = Vector2Add(p_ct->position, offset);
|
||||||
}
|
}
|
||||||
|
@ -299,54 +321,67 @@ collision_end:
|
||||||
static uint8_t check_bbox_edges(
|
static uint8_t check_bbox_edges(
|
||||||
TileGrid_t* tilemap,
|
TileGrid_t* tilemap,
|
||||||
Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox,
|
Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox,
|
||||||
int8_t len_reduction
|
bool ignore_fragile
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint8_t detected = 0;
|
uint8_t detected = 0;
|
||||||
|
|
||||||
bbox.x -= 2 * len_reduction;
|
|
||||||
bbox.y -= 2 * len_reduction;
|
|
||||||
|
|
||||||
CollideEntity_t ent =
|
CollideEntity_t ent =
|
||||||
{
|
{
|
||||||
.p_ent = p_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},
|
.prev_bbox = (Rectangle){pos.x, pos.y, bbox.x, bbox.y},
|
||||||
.area = (TileArea_t){
|
.area = (TileArea_t){
|
||||||
.tile_x1 = (pos.x - 1) / TILE_SIZE,
|
.tile_x1 = (pos.x - 1) / TILE_SIZE,
|
||||||
.tile_y1 = (pos.y) / TILE_SIZE,
|
.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
||||||
.tile_x2 = (pos.x - 1) / TILE_SIZE,
|
.tile_x2 = (pos.x + bbox.x) / TILE_SIZE,
|
||||||
.tile_y2 = (pos.y + bbox.y - 1) / TILE_SIZE,
|
.tile_y2 = (pos.y + bbox.y) / TILE_SIZE,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// TODO: Handle one-way platform
|
// TODO: Handle one-way platform
|
||||||
// Left
|
// 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
|
//Right
|
||||||
ent.bbox.x = pos.x + bbox.x; // 2 to account for the previous subtraction
|
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_x1 = (pos.x + bbox.x) / TILE_SIZE;
|
||||||
ent.area.tile_x2 = ent.area.tile_x1;
|
//ent.area.tile_x2 = ent.area.tile_x1;
|
||||||
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 2;
|
collide_type = check_collision_line(&ent, tilemap, false);
|
||||||
|
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
||||||
|
{
|
||||||
|
detected |= 1 << 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Up
|
// Up
|
||||||
ent.bbox.x = pos.x + len_reduction;
|
ent.bbox.x = pos.x;
|
||||||
ent.bbox.y = pos.y - 1;
|
ent.bbox.y = pos.y - 1;
|
||||||
ent.bbox.width = bbox.x;
|
ent.bbox.width = bbox.x;
|
||||||
ent.bbox.height = 1;
|
ent.bbox.height = 1;
|
||||||
ent.area.tile_x1 = (pos.x) / TILE_SIZE,
|
//ent.area.tile_x1 = (pos.x) / TILE_SIZE,
|
||||||
ent.area.tile_x2 = (pos.x + bbox.x - 1) / 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_y1 = (pos.y - 1) / TILE_SIZE,
|
||||||
ent.area.tile_y2 = ent.area.tile_y1;
|
//ent.area.tile_y2 = ent.area.tile_y1;
|
||||||
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 1;
|
collide_type = check_collision_line(&ent, tilemap, false);
|
||||||
|
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
||||||
|
{
|
||||||
|
detected |= 1 << 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Down
|
// Down
|
||||||
ent.bbox.y = pos.y + bbox.y;
|
ent.bbox.y = pos.y + bbox.y + 1;
|
||||||
ent.area.tile_y1 = (pos.y + bbox.y) / TILE_SIZE,
|
//ent.area.tile_y1 = (pos.y + bbox.y) / TILE_SIZE,
|
||||||
ent.area.tile_y2 = ent.area.tile_y1;
|
//ent.area.tile_y2 = ent.area.tile_y1;
|
||||||
detected |= (check_collision_line(&ent, tilemap, true) ? 1 : 0);
|
collide_type = check_collision_line(&ent, tilemap, false);
|
||||||
|
if (collide_type == 1 || (collide_type == 2 && !ignore_fragile))
|
||||||
|
{
|
||||||
|
detected |= 1;
|
||||||
|
}
|
||||||
return detected;
|
return detected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,7 +721,7 @@ void player_crushing_system(Scene_t* scene)
|
||||||
|
|
||||||
uint8_t edges = check_bbox_edges(
|
uint8_t edges = check_bbox_edges(
|
||||||
&data->tilemap, p_player,
|
&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)
|
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
|
// Post movement edge check to zero out velocity
|
||||||
uint8_t edges = check_bbox_edges(
|
uint8_t edges = check_bbox_edges(
|
||||||
&data->tilemap, p_ent,
|
&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))
|
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
|
// Zero out acceleration for contacts with sturdy entites and tiles
|
||||||
uint8_t edges = check_bbox_edges(
|
uint8_t edges = check_bbox_edges(
|
||||||
&data->tilemap, p_ent,
|
&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))
|
if (edges & (1<<3))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue