Prevent crate bashing at the corner

Changelog:
- Allow two hitboxes in hitbox component
- Create a cross-shaped hitboxes for player
scene_man
En Yi 2023-02-28 20:54:48 +08:00
parent 22b4190947
commit c8ea03359c
4 changed files with 98 additions and 71 deletions

View File

@ -14,7 +14,7 @@ enum ComponentEnum
CJUMP_COMP_T, CJUMP_COMP_T,
CPLAYERSTATE_T, CPLAYERSTATE_T,
CCONTAINER_T, CCONTAINER_T,
CHITBOX_T, CHITBOXES_T,
CHURTBOX_T, CHURTBOX_T,
}; };
typedef enum ComponentEnum ComponentEnum_t; typedef enum ComponentEnum ComponentEnum_t;
@ -97,12 +97,12 @@ typedef struct _CContainer_t
ContainerItem_t item; ContainerItem_t item;
}CContainer_t; }CContainer_t;
typedef struct _CHitBox_t typedef struct _CHitBoxes_t
{ {
Vector2 offset; Rectangle boxes[2];
Vector2 size; uint8_t n_boxes;
bool strong; bool strong;
}CHitBox_t; }CHitBoxes_t;
typedef struct _CHurtbox_t typedef struct _CHurtbox_t
{ {

View File

@ -12,7 +12,7 @@ static CMovementState_t cmstate_buffer[MAX_COMP_POOL_SIZE];
static CJump_t cjump_buffer[1]; // Only player is expected to have this static CJump_t cjump_buffer[1]; // Only player is expected to have this
static CPlayerState_t cplayerstate_buffer[1]; // Only player is expected to have this static CPlayerState_t cplayerstate_buffer[1]; // Only player is expected to have this
static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE]; static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE];
static CHitBox_t chitbox_buffer[MAX_COMP_POOL_SIZE]; static CHitBoxes_t chitboxes_buffer[MAX_COMP_POOL_SIZE];
static CHurtbox_t churtbox_buffer[MAX_COMP_POOL_SIZE]; static CHurtbox_t churtbox_buffer[MAX_COMP_POOL_SIZE];
// Use hashmap as a Set // Use hashmap as a Set
@ -40,7 +40,7 @@ static MemPool_t comp_mempools[N_COMPONENTS] =
{cjump_buffer, 1, sizeof(CJump_t), NULL, {0}}, {cjump_buffer, 1, sizeof(CJump_t), NULL, {0}},
{cplayerstate_buffer, 1, sizeof(CPlayerState_t), NULL, {0}}, {cplayerstate_buffer, 1, sizeof(CPlayerState_t), NULL, {0}},
{ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}}, {ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}},
{chitbox_buffer, MAX_COMP_POOL_SIZE, sizeof(CHitBox_t), NULL, {0}}, {chitboxes_buffer, MAX_COMP_POOL_SIZE, sizeof(CHitBoxes_t), NULL, {0}},
{churtbox_buffer, MAX_COMP_POOL_SIZE, sizeof(CHurtbox_t), NULL, {0}}, {churtbox_buffer, MAX_COMP_POOL_SIZE, sizeof(CHurtbox_t), NULL, {0}},
}; };
static MemPool_t ent_mempool = {entity_buffer, MAX_COMP_POOL_SIZE, sizeof(Entity_t), NULL, {0}}; static MemPool_t ent_mempool = {entity_buffer, MAX_COMP_POOL_SIZE, sizeof(Entity_t), NULL, {0}};

View File

@ -68,17 +68,20 @@ static void level_scene_render_func(Scene_t* scene)
} }
DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour); DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour);
CHurtbox_t* p_hurtbox = get_component(&scene->ent_manager, p_ent, CHURTBOX_T); CHurtbox_t* p_hurtbox = get_component(&scene->ent_manager, p_ent, CHURTBOX_T);
CHitBox_t* p_hitbox = get_component(&scene->ent_manager, p_ent, CHITBOX_T); CHitBoxes_t* p_hitbox = get_component(&scene->ent_manager, p_ent, CHITBOXES_T);
if (p_hitbox != NULL) if (p_hitbox != NULL)
{
for (uint8_t i=0;i<p_hitbox->n_boxes;++i)
{ {
Rectangle rec = { Rectangle rec = {
.x = p_ct->position.x + p_hitbox->offset.x, .x = p_ct->position.x + p_hitbox->boxes[i].x,
.y = p_ct->position.y + p_hitbox->offset.y, .y = p_ct->position.y + p_hitbox->boxes[i].y,
.width = p_hitbox->size.x, .width = p_hitbox->boxes[i].width,
.height = p_hitbox->size.y, .height = p_hitbox->boxes[i].height,
}; };
DrawRectangleLinesEx(rec, 1.5, ORANGE); DrawRectangleLinesEx(rec, 1.5, ORANGE);
} }
}
if (p_hurtbox != NULL) if (p_hurtbox != NULL)
{ {
Rectangle rec = { Rectangle rec = {
@ -185,9 +188,22 @@ static void spawn_player(Scene_t *scene)
add_component(&scene->ent_manager, p_ent, CPLAYERSTATE_T); add_component(&scene->ent_manager, p_ent, CPLAYERSTATE_T);
add_component(&scene->ent_manager, p_ent, CTILECOORD_COMP_T); add_component(&scene->ent_manager, p_ent, CTILECOORD_COMP_T);
add_component(&scene->ent_manager, p_ent, CMOVEMENTSTATE_T); add_component(&scene->ent_manager, p_ent, CMOVEMENTSTATE_T);
CHitBox_t* p_hitbox = add_component(&scene->ent_manager, p_ent, CHITBOX_T); CHitBoxes_t* p_hitbox = add_component(&scene->ent_manager, p_ent, CHITBOXES_T);
p_hitbox->size = Vector2Add(p_bbox->size, (Vector2){2,2}); p_hitbox->n_boxes = 2;
p_hitbox->offset = (Vector2){-1, -1}; p_hitbox->boxes[0] = (Rectangle)
{
.x = p_bbox->size.x / 4,
.y = -1,
.width = p_bbox->size.x / 2,
.height = p_bbox->size.y + 2,
};
p_hitbox->boxes[1] = (Rectangle)
{
.x = -1,
.y = p_bbox->size.y / 4,
.width = p_bbox->size.x + 2 ,
.height = p_bbox->size.y / 2,
};
} }
static void toggle_block_system(Scene_t *scene) static void toggle_block_system(Scene_t *scene)

View File

@ -368,6 +368,11 @@ void player_bbox_update_system(Scene_t *scene)
set_bbox(p_bbox, new_bbox.x, new_bbox.y); set_bbox(p_bbox, new_bbox.x, new_bbox.y);
p_ctransform->position = Vector2Add(p_ctransform->position, offset); p_ctransform->position = Vector2Add(p_ctransform->position, offset);
} }
CHitBoxes_t* p_hitbox = get_component(&scene->ent_manager, p_player, CHITBOXES_T);
p_hitbox->boxes[0].height = p_bbox->size.y + 2;
p_hitbox->boxes[1].y = p_bbox->size.y / 4;
p_hitbox->boxes[1].height = p_bbox->size.y / 2;
} }
} }
@ -741,18 +746,23 @@ void hitbox_update_system(Scene_t *scene)
TileGrid_t tilemap = data->tilemap; TileGrid_t tilemap = data->tilemap;
unsigned int ent_idx; unsigned int ent_idx;
CHitBox_t* p_hitbox; CHitBoxes_t* p_hitbox;
//sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) //sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
sc_map_foreach(&scene->ent_manager.component_map[CHITBOX_T], ent_idx, p_hitbox) sc_map_foreach(&scene->ent_manager.component_map[CHITBOXES_T], ent_idx, p_hitbox)
{ {
Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx); Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx);
CTransform_t* p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T); CTransform_t* p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T);
Vector2 hitbox_pos = Vector2Add(p_ctransform->position, p_hitbox->offset); for (uint8_t i=0;i<p_hitbox->n_boxes;++i)
{
Vector2 hitbox_pos = {
.x = p_ctransform->position.x + p_hitbox->boxes[i].x,
.y = p_ctransform->position.y + p_hitbox->boxes[i].y,
};
unsigned int tile_x1 = (hitbox_pos.x) / TILE_SIZE; unsigned int tile_x1 = (hitbox_pos.x) / TILE_SIZE;
unsigned int tile_y1 = (hitbox_pos.y) / TILE_SIZE; unsigned int tile_y1 = (hitbox_pos.y) / TILE_SIZE;
unsigned int tile_x2 = (hitbox_pos.x + p_hitbox->size.x - 1) / TILE_SIZE; unsigned int tile_x2 = (hitbox_pos.x + p_hitbox->boxes[i].width - 1) / TILE_SIZE;
unsigned int tile_y2 = (hitbox_pos.y + p_hitbox->size.y - 1) / TILE_SIZE; unsigned int tile_y2 = (hitbox_pos.y + p_hitbox->boxes[i].height - 1) / TILE_SIZE;
for (unsigned int tile_y=tile_y1; tile_y <= tile_y2; tile_y++) for (unsigned int tile_y=tile_y1; tile_y <= tile_y2; tile_y++)
{ {
@ -776,7 +786,7 @@ void hitbox_update_system(Scene_t *scene)
Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset); Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset);
Vector2 overlap; Vector2 overlap;
if (find_AABB_overlap(hitbox_pos, p_hitbox->size, hurtbox_pos, p_other_hurtbox->size, &overlap)) if (find_AABB_overlap(hitbox_pos, (Vector2){p_hitbox->boxes[i].width, p_hitbox->boxes[i].height}, hurtbox_pos, p_other_hurtbox->size, &overlap))
{ {
if (!p_other_hurtbox->fragile) continue; if (!p_other_hurtbox->fragile) continue;
if (p_other_ent->m_tag == CRATES_ENT_TAG) if (p_other_ent->m_tag == CRATES_ENT_TAG)
@ -814,6 +824,7 @@ void hitbox_update_system(Scene_t *scene)
} }
} }
} }
}
} }
void init_level_scene_data(LevelSceneData_t *data) void init_level_scene_data(LevelSceneData_t *data)