Merge pull request 'implement basic collision and interpolation' (#6) from collision into main
Reviewed-on: #6main
commit
96eeb3233f
|
@ -110,7 +110,7 @@ static inline
|
||||||
short _collision_circle_aabb(const object_t* circle, const object_t* aabb) {
|
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
|
// 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,
|
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,
|
const float cx = circle->sprite.x + circle->collider.circle.x,
|
||||||
cy = circle->sprite.y + circle->collider.circle.y;
|
cy = circle->sprite.y + circle->collider.circle.y;
|
||||||
const float x = fclampf(cx, bbminx, bbmaxx),
|
const float x = fclampf(cx, bbminx, bbmaxx),
|
||||||
|
@ -141,7 +141,13 @@ short _collision_check(const object_t* a, const object_t* b) {
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
short _can_collide(const object_t* object) {
|
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() {
|
void update_collision() {
|
||||||
|
@ -153,8 +159,8 @@ void update_collision() {
|
||||||
if(!_can_collide(oobject)) continue;
|
if(!_can_collide(oobject)) continue;
|
||||||
|
|
||||||
if(outer != inner && _collision_check(iobject, oobject)) {
|
if(outer != inner && _collision_check(iobject, oobject)) {
|
||||||
oobject->collider.evt_collision(oobject, iobject);
|
object_broadcast_collision(oobject, iobject);
|
||||||
iobject->collider.evt_collision(iobject, oobject);
|
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
|
// ensure this object would ever collide
|
||||||
// if it wouldn't collide anyway, just set position
|
// if it wouldn't collide anyway, just set position
|
||||||
if(_can_collide(object)) {
|
if(!_can_collide(object)) {
|
||||||
object->sprite.x = target_x;
|
object->sprite.x = target_x;
|
||||||
object->sprite.y = target_y;
|
object->sprite.y = target_y;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1. check collision with every other object
|
* 1. move towards target
|
||||||
* 2. move towards target
|
* 2. check collision with every other object
|
||||||
*/
|
*/
|
||||||
while(object->sprite.x != target_x || object->sprite.y != target_y) {
|
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
|
// 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)) {
|
if(distx < fabsf(dx) && disty < fabsf(dy)) {
|
||||||
object->sprite.x += dx; object->sprite.y += dy;
|
object->sprite.x += dx;
|
||||||
|
object->sprite.y += dy;
|
||||||
} else {
|
} else {
|
||||||
object->sprite.x = target_x;
|
object->sprite.x = target_x;
|
||||||
object->sprite.y = target_y;
|
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
|
// no collision, return nothing
|
||||||
|
|
|
@ -55,6 +55,7 @@ object_t* instantiate_object(const object_t* original);
|
||||||
collider_t collider_default();
|
collider_t collider_default();
|
||||||
|
|
||||||
void object_draw_sprite(object_t* object);
|
void object_draw_sprite(object_t* object);
|
||||||
|
void object_broadcast_evt_collision(object_t* this, object_t* other);
|
||||||
|
|
||||||
void update_objects();
|
void update_objects();
|
||||||
void draw_objects();
|
void draw_objects();
|
||||||
|
|
Loading…
Reference in New Issue