From edbedae70315222b890e39bf532d665ac379e867 Mon Sep 17 00:00:00 2001 From: Ulysse Cura Date: Tue, 4 Aug 2026 21:53:37 +0200 Subject: [PATCH] Hitboxes between entities are handled by the physics component. --- SDL3_Core | 2 +- TODO.md | 4 +- src/components/headers/physics_system.h | 2 + src/components/physics_system.c | 81 ++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 13 deletions(-) diff --git a/SDL3_Core b/SDL3_Core index 34ee7e2..1f3a17a 160000 --- a/SDL3_Core +++ b/SDL3_Core @@ -1 +1 @@ -Subproject commit 34ee7e2a57079f8e5b00af4183d14ed75b35d8b8 +Subproject commit 1f3a17a46599e6aa9f5f261924db8287d883a778 diff --git a/TODO.md b/TODO.md index f9db5c3..557fbbf 100644 --- a/TODO.md +++ b/TODO.md @@ -22,10 +22,10 @@ ### In progress -- [ ] Make functionnal hitboxes between entities - ### Done +- [x] Make functionnal hitboxes between entities + - [x] Change the way default values are defined across components and systems - [NO] Remove the need of a dummy texture diff --git a/src/components/headers/physics_system.h b/src/components/headers/physics_system.h index 118164e..9704f6e 100644 --- a/src/components/headers/physics_system.h +++ b/src/components/headers/physics_system.h @@ -3,10 +3,12 @@ #include "ecs.h" #include "transform_component.h" +#include "hitbox_component.h" #include "vector2d.h" typedef struct physics_system_data_t { transform_component_data_t *transform_component_data; + hitbox_component_data_t *hitbox_component_data; fvector2d_t target_velocity; fvector2d_t velocity; float speed; diff --git a/src/components/physics_system.c b/src/components/physics_system.c index 78e03d4..1f704e7 100644 --- a/src/components/physics_system.c +++ b/src/components/physics_system.c @@ -1,15 +1,19 @@ #include "physics_system.h" +#include +#include "vector2d.h" #include "memory_alloc.h" #include "game.h" +#include "errors.h" // Args : frect_t bounds, double speed int physics_system_init(component_t *component) { physics_system_data_t *system_data = component->data; - system_data->transform_component_data = entity_get_component(component->entity, TRANSFORM_COMPONENT)->data; - if(!system_data->transform_component_data) return EXIT_FAILURE; + system_data->hitbox_component_data = entity_get_component(component->entity, HITBOX_COMPONENT)->data; + if(!system_data->hitbox_component_data) return EXIT_FAILURE; + system_data->transform_component_data = system_data->hitbox_component_data->transform_component_data; system_data->target_velocity = (fvector2d_t) { .x = 0.0f, @@ -28,24 +32,81 @@ int physics_system_init(component_t *component) return EXIT_SUCCESS; } -static inline void physics_system_update_pos(physics_system_data_t *system_data) +// Only for this file +// Args : physics_system_data_t *system_data, size_t entity_id +static inline int action_check_hitboxes(elem_t *elem, va_list args) { - transform_component_data_t *transform_component_data = system_data->transform_component_data; + const entity_t *target_entity = elem->data; + physics_system_data_t *system_data = va_arg(args, physics_system_data_t *); - system_data->velocity.x = lerp(system_data->velocity.x, system_data->target_velocity.x, system_data->smoothing_factor); - system_data->velocity.y = lerp(system_data->velocity.y, system_data->target_velocity.y, system_data->smoothing_factor); + if(target_entity->id == va_arg(args, size_t)) + { + return EXIT_SUCCESS; + } - transform_component_data->bounds.x += system_data->velocity.x * system_data->speed * (float)game.delta_time_ms / 1000.0f; - transform_component_data->bounds.y += system_data->velocity.y * system_data->speed * (float)game.delta_time_ms / 1000.0f; + const component_t *target_hitbox_component = entity_get_component(target_entity, HITBOX_COMPONENT); + if(!target_hitbox_component) return EXIT_SUCCESS; + + if(!((hitbox_component_data_t *)target_hitbox_component->data)->activated) + { + return EXIT_SUCCESS; + } + + const frect_t *hitbox_bounds = &system_data->hitbox_component_data->bounds; + const frect_t *target_hitbox_bounds = &((hitbox_component_data_t *)target_hitbox_component->data)->bounds; + frect_t intersect_frect; + + if(intersect_frect(hitbox_bounds, target_hitbox_bounds, &intersect_frect)) + { + if(intersect_frect.w < intersect_frect.h) + { + const float left_correction = hitbox_bounds->x + hitbox_bounds->w - target_hitbox_bounds->x; + const float right_correction = target_hitbox_bounds->x + target_hitbox_bounds->w - hitbox_bounds->x; + + if(left_correction < right_correction) + { + system_data->transform_component_data->bounds.x -= left_correction; + if(system_data->velocity.x > 0.0f) system_data->velocity.x = 0.0f; + } + else + { + system_data->transform_component_data->bounds.x += right_correction; + if(system_data->velocity.x < 0.0f) system_data->velocity.x = 0.0f; + } + } + else + { + float top_correction = hitbox_bounds->y + hitbox_bounds->h - target_hitbox_bounds->y; + float bottom_correction = target_hitbox_bounds->y + target_hitbox_bounds->h - hitbox_bounds->y; + + if(top_correction < bottom_correction) + { + system_data->transform_component_data->bounds.y -= top_correction; + if(system_data->velocity.y > 0.0f) system_data->velocity.y = 0.0f; + } + else + { + system_data->transform_component_data->bounds.y += bottom_correction; + if(system_data->velocity.y < 0.0f) system_data->velocity.y = 0.0f; + } + } + } + + return EXIT_SUCCESS; } int physics_system_update(component_t *component) { physics_system_data_t *system_data = component->data; + transform_component_data_t *transform_component_data = system_data->transform_component_data; - physics_system_update_pos(system_data); + system_data->velocity.x = lerp(system_data->velocity.x, system_data->target_velocity.x, system_data->smoothing_factor); + system_data->velocity.y = lerp(system_data->velocity.y, system_data->target_velocity.y, system_data->smoothing_factor); -// linked_list_for_each(&game.entity_manager.entities, ); + linked_list_for_each(&game.entity_manager.entities, action_check_hitboxes, system_data, component->entity->id); + + transform_component_data->bounds.x += system_data->velocity.x * system_data->speed * (float)game.delta_time_ms / 1000.0f; + transform_component_data->bounds.y += system_data->velocity.y * system_data->speed * (float)game.delta_time_ms / 1000.0f; return EXIT_SUCCESS; }