From f8d69e3537814d44017879605e35af8ef66c5a5e Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 18 Jun 2023 11:39:16 +0200 Subject: [PATCH 1/7] reversed order of operations in interpolate_move --- src/corelib/world.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/corelib/world.c b/src/corelib/world.c index ce41dea..043175a 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -177,28 +177,32 @@ object_t* interpolate_move(object_t* object, float target_x, float target_y, flo } /* - * 1. check collision with every other object - * 2. move towards target + * 1. move towards target + * 2. check collision with every other object */ while(object->sprite.x != target_x || object->sprite.y != target_y) { - for(int i = 0; i < WORLD_NUM_OBJECTS; ++i) { - object_t* other = g_objects + i; - if(!_can_collide(other)) continue; - if(object != other && _collision_check(other, object)) { - other->collider.evt_collision(other, object); - object->collider.evt_collision(object, other); - return other; - } - } - // move towards target, snap to target if distance is too low - float distx = fabsf(object->sprite.x - target_x), disty = fabsf(object->sprite.y - target_y); + const float old_x = object->sprite.x, old_y = object->sprite.y; + const float distx = fabsf(object->sprite.x - target_x), disty = fabsf(object->sprite.y - target_y); if(distx < fabsf(dx) && disty < fabsf(dy)) { object->sprite.x += dx; object->sprite.y += dy; } else { object->sprite.x = target_x; object->sprite.y = target_y; } + + // loop over all objects and check collision if applicable + for(int i = 0; i < WORLD_NUM_OBJECTS; ++i) { + // get pointer to other object + object_t* other = g_objects + i; + if(!_can_collide(other)) continue; + // check collision, return if found + if(object != other && _collision_check(other, object)) { + other->collider.evt_collision(other, object); + object->collider.evt_collision(object, other); + return other; + } + } } // no collision, return nothing -- 2.34.1 From 8ae7d302fee8f9a8ea61f381710fac1e22b63d14 Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 18 Jun 2023 11:59:13 +0200 Subject: [PATCH 2/7] inverted _can_collide guard clause in interpolate_move --- src/corelib/world.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/world.c b/src/corelib/world.c index 043175a..7476271 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -170,7 +170,7 @@ object_t* interpolate_move(object_t* object, float target_x, float target_y, flo // ensure this object would ever collide // if it wouldn't collide anyway, just set position - if(_can_collide(object)) { + if(!_can_collide(object)) { object->sprite.x = target_x; object->sprite.y = target_y; return NULL; -- 2.34.1 From 0b32967c20abe858309b8cbcd6fe327dbda2f0f8 Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 18 Jun 2023 13:13:35 +0200 Subject: [PATCH 3/7] removed requirement for a evt_collision listener from _can_collide --- src/corelib/world.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/world.c b/src/corelib/world.c index 7476271..a513867 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -141,7 +141,7 @@ short _collision_check(const object_t* a, const object_t* b) { static inline short _can_collide(const object_t* object) { - return object->active && object->enabled && object->collider.evt_collision != NULL; + return object->active && object->enabled; } void update_collision() { -- 2.34.1 From e32eb731c2955b595fd6bb120c49f2426610aa39 Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 18 Jun 2023 13:15:03 +0200 Subject: [PATCH 4/7] simplified interpolate move comparison condition --- src/corelib/world.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/world.c b/src/corelib/world.c index a513867..11a8d82 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -195,9 +195,8 @@ object_t* interpolate_move(object_t* object, float target_x, float target_y, flo for(int i = 0; i < WORLD_NUM_OBJECTS; ++i) { // get pointer to other object object_t* other = g_objects + i; - if(!_can_collide(other)) continue; // check collision, return if found - if(object != other && _collision_check(other, object)) { + if(_can_collide(other) && object != other && _collision_check(other, object)) { other->collider.evt_collision(other, object); object->collider.evt_collision(object, other); return other; -- 2.34.1 From 4bf759d2240b59b5ed7882fb9275e95f4481fe83 Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 18 Jun 2023 13:22:35 +0200 Subject: [PATCH 5/7] added broadcast collision --- src/corelib/world.c | 14 ++++++++++---- src/corelib/world.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/world.c b/src/corelib/world.c index 11a8d82..957655e 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -144,6 +144,12 @@ short _can_collide(const object_t* object) { return object->active && object->enabled; } +void object_broadcast_collision(object_t* this, object_t* other) { + if(this->collider.evt_collision != NULL) { + this->collider.evt_collision(this, other); + } +} + void update_collision() { for(int outer = 0; outer < WORLD_NUM_OBJECTS; ++outer) { object_t* oobject = g_objects + outer; @@ -153,8 +159,8 @@ void update_collision() { if(!_can_collide(oobject)) continue; if(outer != inner && _collision_check(iobject, oobject)) { - oobject->collider.evt_collision(oobject, iobject); - iobject->collider.evt_collision(iobject, oobject); + object_broadcast_collision(oobject, iobject); + object_broadcast_collision(iobject, oobject); } } } @@ -197,8 +203,8 @@ object_t* interpolate_move(object_t* object, float target_x, float target_y, flo object_t* other = g_objects + i; // check collision, return if found if(_can_collide(other) && object != other && _collision_check(other, object)) { - other->collider.evt_collision(other, object); - object->collider.evt_collision(object, other); + object_broadcast_collision(other, object); + object_broadcast_collision(object, other); return other; } } diff --git a/src/corelib/world.h b/src/corelib/world.h index d82287a..2c57f31 100644 --- a/src/corelib/world.h +++ b/src/corelib/world.h @@ -55,6 +55,7 @@ object_t* instantiate_object(const object_t* original); collider_t collider_default(); void object_draw_sprite(object_t* object); +void object_broadcast_evt_collision(object_t* this, object_t* other); void update_objects(); void draw_objects(); -- 2.34.1 From d134df5847b2b88da6c524a6affd36fe0c90946a Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 18 Jun 2023 13:42:20 +0200 Subject: [PATCH 6/7] position now resets to last when interpolate_move collides --- src/corelib/world.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/world.c b/src/corelib/world.c index 957655e..fa92ea7 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -191,7 +191,8 @@ object_t* interpolate_move(object_t* object, float target_x, float target_y, flo const float old_x = object->sprite.x, old_y = object->sprite.y; const float distx = fabsf(object->sprite.x - target_x), disty = fabsf(object->sprite.y - target_y); if(distx < fabsf(dx) && disty < fabsf(dy)) { - object->sprite.x += dx; object->sprite.y += dy; + object->sprite.x += dx; + object->sprite.y += dy; } else { object->sprite.x = target_x; object->sprite.y = target_y; @@ -205,6 +206,8 @@ object_t* interpolate_move(object_t* object, float target_x, float target_y, flo if(_can_collide(other) && object != other && _collision_check(other, object)) { object_broadcast_collision(other, object); object_broadcast_collision(object, other); + object->sprite.x = old_x; + object->sprite.y = old_y; return other; } } -- 2.34.1 From bd87bcf8afb755e2a215ad939508a7277a3f851d Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 18 Jun 2023 13:45:53 +0200 Subject: [PATCH 7/7] bbminy in _collision_circle_aabb is now calculated correctly using y --- src/corelib/world.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/world.c b/src/corelib/world.c index fa92ea7..85fbed4 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -110,7 +110,7 @@ static inline short _collision_circle_aabb(const object_t* circle, const object_t* aabb) { // generate a point on the edge of the rectangle that is closest to the circle const float bbminx = aabb->collider.aabb.x + aabb->sprite.x, bbmaxx = bbminx + aabb->collider.aabb.w, - bbminy = aabb->collider.aabb.y + aabb->sprite.x, bbmaxy = bbminy + aabb->collider.aabb.h; + bbminy = aabb->collider.aabb.y + aabb->sprite.y, bbmaxy = bbminy + aabb->collider.aabb.h; const float cx = circle->sprite.x + circle->collider.circle.x, cy = circle->sprite.y + circle->collider.circle.y; const float x = fclampf(cx, bbminx, bbmaxx), -- 2.34.1