From e8ebe0f89c87c67b8ea34baff861623b4b70e0f6 Mon Sep 17 00:00:00 2001 From: En Yi Date: Sat, 23 Sep 2023 00:28:03 +0800 Subject: [PATCH] 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 --- scenes/editor_scene.c | 6 +++++- scenes/engine/collisions.c | 1 - scenes/game_systems.c | 40 ++++++++++++++++++++++++++++++-------- scenes/game_systems.h | 1 + scenes/items_ent.c | 2 +- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/scenes/editor_scene.c b/scenes/editor_scene.c index f4457c7..4f73a33 100644 --- a/scenes/editor_scene.c +++ b/scenes/editor_scene.c @@ -213,7 +213,10 @@ static void level_scene_render_func(Scene_t* scene) colour = RED; break; 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; case BOULDER_ENT_TAG: 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, &player_crushing_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, &player_ground_air_transition_system); sc_array_add(&scene->scene.systems, &lifetimer_update_system); diff --git a/scenes/engine/collisions.c b/scenes/engine/collisions.c index ee71f9d..a89edf7 100644 --- a/scenes/engine/collisions.c +++ b/scenes/engine/collisions.c @@ -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); CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T); if (p_bbox == NULL || p_ctransform == NULL) continue; - //if (p_bbox->solid && !p_bbox->fragile) if (p_bbox->solid) { Rectangle box = { diff --git a/scenes/game_systems.c b/scenes/game_systems.c index 112ddc7..bea20a9 100644 --- a/scenes/game_systems.c +++ b/scenes/game_systems.c @@ -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 uint8_t edges = check_bbox_edges( &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)) { @@ -1443,6 +1456,7 @@ void hitbox_update_system(Scene_t* scene) CHurtbox_t* p_other_hurtbox = get_component(p_other_ent, CHURTBOX_T); if (p_other_hurtbox == NULL) continue; 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); if ( @@ -1469,16 +1483,26 @@ void hitbox_update_system(Scene_t* scene) CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T); if ( p_pstate != NULL - && p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y ) { - p_ctransform->velocity.y = -400; - if (p_pstate->jump_pressed) + if (p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y + p_other_bbox->half_size.y / 2) { - 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; + p_ctransform->velocity.y = -400; + if (p_pstate->jump_pressed) + { + 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; } } } diff --git a/scenes/game_systems.h b/scenes/game_systems.h index 54d0d08..2b6b8b7 100644 --- a/scenes/game_systems.h +++ b/scenes/game_systems.h @@ -15,6 +15,7 @@ void player_ground_air_transition_system(Scene_t* scene); void state_transition_update_system(Scene_t* scene); void update_tilemap_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 boulder_destroy_wooden_tile_system(Scene_t* scene); void camera_update_system(Scene_t* scene); diff --git a/scenes/items_ent.c b/scenes/items_ent.c index 3e1a8a7..809dabd 100644 --- a/scenes/items_ent.c +++ b/scenes/items_ent.c @@ -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); p_cspr->sprites = item_sprite_map; - if (item != CONTAINER_EMPTY) { CContainer_t* p_container = add_component(p_crate, CCONTAINER_T); + p_container->material = metal? METAL_CONTAINER : WOODEN_CONTAINER; p_container->item = item; } switch(item)