Improve crushing using edge testing

Changelog:
- Add len reduction to edge checking to give leeway in crushing
scene_man
En Yi 2023-06-21 21:27:13 +08:00
parent 4b91ab5667
commit c8d2ee5408
2 changed files with 17 additions and 50 deletions

View File

@ -477,7 +477,7 @@ void init_level_scene(LevelScene_t* scene)
sc_array_add(&scene->scene.systems, &tile_collision_system);
sc_array_add(&scene->scene.systems, &update_tilemap_system);
sc_array_add(&scene->scene.systems, &hitbox_update_system);
//sc_array_add(&scene->scene.systems, &player_crushing_system);
sc_array_add(&scene->scene.systems, &player_crushing_system);
sc_array_add(&scene->scene.systems, &state_transition_update_system);
sc_array_add(&scene->scene.systems, &player_ground_air_transition_system);
sc_array_add(&scene->scene.systems, &sprite_animation_system);

View File

@ -298,14 +298,19 @@ collision_end:
static uint8_t check_bbox_edges(
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
)
{
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, 1, bbox.y},
.bbox = (Rectangle){pos.x - 1, pos.y + len_reduction, 1, bbox.y},
.prev_bbox = (Rectangle){pos.x, pos.y, bbox.x, bbox.y},
.area = (TileArea_t){
.tile_x1 = (pos.x - 1) / TILE_SIZE,
@ -327,8 +332,8 @@ static uint8_t check_bbox_edges(
detected |= (check_collision_line(&ent, tilemap, false) ? 1 : 0) << 2;
// Up
ent.bbox.x = pos.x;
ent.bbox.y--;
ent.bbox.x = pos.x + len_reduction;
ent.bbox.y = pos.y - 1;
ent.bbox.width = bbox.x;
ent.bbox.height = 1;
ent.area.tile_x1 = (pos.x) / TILE_SIZE,
@ -672,57 +677,19 @@ void player_bbox_update_system(Scene_t* scene)
void player_crushing_system(Scene_t* scene)
{
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
TileGrid_t tilemap = data->tilemap;
Entity_t* p_player;
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
{
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
CollideEntity_t ent =
{
.p_ent = p_player,
.bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
.prev_bbox = (Rectangle){p_ctransform->prev_velocity.x, p_ctransform->prev_position.y, p_bbox->size.x, p_bbox->size.y},
.area = (TileArea_t){
.tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
.tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
.tile_x2 = (p_ctransform->position.x) / TILE_SIZE,
.tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
},
};
// Mostly identical to edge check function
// Except we want collision instead of just touching
uint8_t detected = 0;
// Left
detected |= (check_collision(&ent, &tilemap, false) ? 1 : 0);
uint8_t edges = check_bbox_edges(
&data->tilemap, p_player,
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 2
);
//Right
ent.area.tile_x1 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE;
ent.area.tile_x2 = ent.area.tile_x1;
detected |= (check_collision(&ent, &tilemap, false) ? 1 : 0) << 1;
if (detected == 0b11)
{
p_player->m_alive = false;
return;
}
detected = 0;
// Up
ent.area.tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
ent.area.tile_y1 = (p_ctransform->position.y - 1) / TILE_SIZE,
ent.area.tile_y2 = ent.area.tile_y1;
detected |= (check_collision(&ent, &tilemap, false) ? 1 : 0) << 1;
// Down
ent.area.tile_y1 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
ent.area.tile_y2 = ent.area.tile_y1;
detected |= (check_collision(&ent, &tilemap, true) ? 1 : 0);
//if (check_collision(&ent, &tilemap, false) == 1)
if (detected == 0b11)
if ((edges & 0b1100) == 0b1100 || (edges & 0b0011) == 0b0011)
{
p_player->m_alive = false;
return;
@ -801,7 +768,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
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 0
);
if (edges & (1<<3))
{
@ -927,7 +894,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
p_ctransform->position, p_ctransform->prev_position, p_bbox->size, 0
);
if (edges & (1<<3))
{