diff --git a/src/corelib/world.c b/src/corelib/world.c index ce41dea..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), @@ -141,7 +141,13 @@ 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 object_broadcast_collision(object_t* this, object_t* other) { + if(this->collider.evt_collision != NULL) { + this->collider.evt_collision(this, other); + } } void update_collision() { @@ -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); } } } @@ -170,35 +176,41 @@ 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; } /* - * 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; + 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; + // check collision, return if found + 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; + } + } } // no collision, return nothing 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();