Improve player collision to chests vs crates

Internal Changelog:
- Delay zeroing velocity on edge check to after hitbox update
- Update player velocity on hitting a crate explicitly
    - This is due to the zeroing velocity changes above
    - This essentially allow 'phasing' through chest but not wooden
      crates
- Render crates using material instead of fragile flag
scene_man
En Yi 2023-09-23 00:28:03 +08:00
parent a8e0d99870
commit e8ebe0f89c
5 changed files with 39 additions and 11 deletions

View File

@ -213,7 +213,10 @@ static void level_scene_render_func(Scene_t* scene)
colour = RED; colour = RED;
break; break;
case CRATES_ENT_TAG: case CRATES_ENT_TAG:
colour = p_bbox->fragile? BROWN : GRAY; {
CContainer_t* p_container = get_component(p_ent, CCONTAINER_T);
colour = p_container->material == WOODEN_CONTAINER ? BROWN : GRAY;
}
break; break;
case BOULDER_ENT_TAG: case BOULDER_ENT_TAG:
colour = GRAY; colour = GRAY;
@ -946,6 +949,7 @@ void init_sandbox_scene(LevelScene_t* scene)
sc_array_add(&scene->scene.systems, &hitbox_update_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, &spike_collision_system); sc_array_add(&scene->scene.systems, &spike_collision_system);
sc_array_add(&scene->scene.systems, &edge_velocity_check_system);
sc_array_add(&scene->scene.systems, &state_transition_update_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, &player_ground_air_transition_system);
sc_array_add(&scene->scene.systems, &lifetimer_update_system); sc_array_add(&scene->scene.systems, &lifetimer_update_system);

View File

@ -137,7 +137,6 @@ uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool
CTransform_t *p_ctransform = get_component(p_other_ent, CTRANSFORM_COMP_T); CTransform_t *p_ctransform = get_component(p_other_ent, CTRANSFORM_COMP_T);
CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T); CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T);
if (p_bbox == NULL || p_ctransform == NULL) continue; if (p_bbox == NULL || p_ctransform == NULL) continue;
//if (p_bbox->solid && !p_bbox->fragile)
if (p_bbox->solid) if (p_bbox->solid)
{ {
Rectangle box = { Rectangle box = {

View File

@ -684,10 +684,23 @@ void tile_collision_system(Scene_t* scene)
} }
} }
}
}
void edge_velocity_check_system(Scene_t* scene)
{
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
unsigned int ent_idx;
CBBox_t* p_bbox;
sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox)
{
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
if (!p_ctransform->active) continue;
// 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, true p_ctransform->position, p_ctransform->prev_position, p_bbox->size, false
); );
if (edges & (1<<3)) if (edges & (1<<3))
{ {
@ -1443,6 +1456,7 @@ void hitbox_update_system(Scene_t* scene)
CHurtbox_t* p_other_hurtbox = get_component(p_other_ent, CHURTBOX_T); CHurtbox_t* p_other_hurtbox = get_component(p_other_ent, CHURTBOX_T);
if (p_other_hurtbox == NULL) continue; if (p_other_hurtbox == NULL) continue;
CTransform_t* p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T); CTransform_t* p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T);
CBBox_t* p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset); Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset);
if ( if (
@ -1469,16 +1483,26 @@ void hitbox_update_system(Scene_t* scene)
CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T); CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T);
if ( if (
p_pstate != NULL p_pstate != NULL
&& p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y
) )
{ {
p_ctransform->velocity.y = -400; if (p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y + p_other_bbox->half_size.y / 2)
if (p_pstate->jump_pressed)
{ {
p_ctransform->velocity.y = -600; p_ctransform->velocity.y = -400;
CJump_t * p_cjump = get_component(p_ent, CJUMP_COMP_T); if (p_pstate->jump_pressed)
p_cjump->short_hop = false; {
p_cjump->jumped = true; p_ctransform->velocity.y = -600;
CJump_t * p_cjump = get_component(p_ent, CJUMP_COMP_T);
p_cjump->short_hop = false;
p_cjump->jumped = true;
}
}
else if (p_ctransform->position.y > p_other_ct->position.y + p_other_bbox->half_size.y * 1.5)
{
p_ctransform->velocity.y = 0;
}
else
{
p_ctransform->velocity.x = 0;
} }
} }
} }

View File

@ -15,6 +15,7 @@ void player_ground_air_transition_system(Scene_t* scene);
void state_transition_update_system(Scene_t* scene); void state_transition_update_system(Scene_t* scene);
void update_tilemap_system(Scene_t* scene); void update_tilemap_system(Scene_t* scene);
void hitbox_update_system(Scene_t* scene); void hitbox_update_system(Scene_t* scene);
void edge_velocity_check_system(Scene_t* scene);
void sprite_animation_system(Scene_t* scene); void sprite_animation_system(Scene_t* scene);
void boulder_destroy_wooden_tile_system(Scene_t* scene); void boulder_destroy_wooden_tile_system(Scene_t* scene);
void camera_update_system(Scene_t* scene); void camera_update_system(Scene_t* scene);

View File

@ -53,9 +53,9 @@ Entity_t* create_crate(EntityManager_t* ent_manager, Assets_t* assets, bool meta
CSprite_t* p_cspr = add_component(p_crate, CSPRITE_T); CSprite_t* p_cspr = add_component(p_crate, CSPRITE_T);
p_cspr->sprites = item_sprite_map; p_cspr->sprites = item_sprite_map;
if (item != CONTAINER_EMPTY)
{ {
CContainer_t* p_container = add_component(p_crate, CCONTAINER_T); CContainer_t* p_container = add_component(p_crate, CCONTAINER_T);
p_container->material = metal? METAL_CONTAINER : WOODEN_CONTAINER;
p_container->item = item; p_container->item = item;
} }
switch(item) switch(item)