diff --git a/src/corelib/world.c b/src/corelib/world.c index 11a26f6..ce41dea 100644 --- a/src/corelib/world.c +++ b/src/corelib/world.c @@ -67,12 +67,7 @@ void draw_objects() { } static inline -short _collision_aabb_aabb(const object_t* a, const object_t* b) { - const float aminx = a->collider.aabb.x + a->sprite.x, aminy = a->collider.aabb.y + a->sprite.x; - const float amaxx = aminx + a->collider.aabb.w, amaxy = aminy + a->collider.aabb.h; - const float bminx = b->collider.aabb.x, bminy = b->collider.aabb.y; - const float bmaxx = b->collider.aabb.x + b->collider.aabb.w, bmaxy = b->collider.aabb.y + b->collider.aabb.h; - +int _rect_overlap(float aminx, float aminy, float amaxx, float amaxy, float bminx, float bminy, float bmaxx, float bmaxy) { return ( (aminx < bmaxx && aminx > bmaxx) @@ -85,6 +80,16 @@ short _collision_aabb_aabb(const object_t* a, const object_t* b) { ); } +static inline +short _collision_aabb_aabb(const object_t* a, const object_t* b) { + const float aminx = a->collider.aabb.x + a->sprite.x, aminy = a->collider.aabb.y + a->sprite.x; + const float amaxx = aminx + a->collider.aabb.w, amaxy = aminy + a->collider.aabb.h; + const float bminx = b->collider.aabb.x, bminy = b->collider.aabb.y; + const float bmaxx = b->collider.aabb.x + b->collider.aabb.w, bmaxy = b->collider.aabb.y + b->collider.aabb.h; + + return _rect_overlap(aminx, aminy, amaxx, amaxy, bminx, bminy, bmaxx, bmaxy); +} + static inline short _collision_circle_circle(const object_t* a, const object_t* b) { const float ax = a->sprite.x + a->collider.circle.x, ay = a->sprite.y + a->collider.circle.y, @@ -143,7 +148,7 @@ void update_collision() { for(int outer = 0; outer < WORLD_NUM_OBJECTS; ++outer) { object_t* oobject = g_objects + outer; if(!_can_collide(oobject)) continue; - for(int inner = 0; inner < WORLD_NUM_OBJECTS/2; ++inner) { + for(int inner = 0; inner < WORLD_NUM_OBJECTS; ++inner) { object_t* iobject = g_objects + inner; if(!_can_collide(oobject)) continue; @@ -154,3 +159,48 @@ void update_collision() { } } } + +object_t* interpolate_move(object_t* object, float target_x, float target_y, float max_step_size) { + // calculate step delta + float dx = target_x - object->sprite.x, dy = target_y - object->sprite.y; + // calculate direction x,y + float m = sqrtf(dx*dx + dy*dy); + dx /= m; dy /= m; + dx *= max_step_size; dy *= max_step_size; + + // ensure this object would ever collide + // if it wouldn't collide anyway, just set position + 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 + */ + 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); + 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; + } + } + + // no collision, return nothing + return NULL; +} diff --git a/src/corelib/world.h b/src/corelib/world.h index 884b23f..d82287a 100644 --- a/src/corelib/world.h +++ b/src/corelib/world.h @@ -61,4 +61,6 @@ void draw_objects(); void update_collision(); +object_t* interpolate_move(object_t* object, float target_x, float target_y, float max_step_size); + #endif /* _world_h */