X-Git-Url: https://git.rohieb.name/hackover2013-badge-firmware.git/blobdiff_plain/4cb2d309b35bc7acc33483bdcd0af2a749206369..ac05cee74d9922fdca433dd2c03fd8542002bb28:/badge/jumpnrun/collision.c diff --git a/badge/jumpnrun/collision.c b/badge/jumpnrun/collision.c index 34ab099..20617bb 100644 --- a/badge/jumpnrun/collision.c +++ b/badge/jumpnrun/collision.c @@ -1,83 +1,98 @@ #include "collision.h" -void collision_displace(vec2d *desired_pos, - jumpnrun_moveable *current, - rectangle const *obstacle, - vec2d *inertia_mod) { - rectangle desired = current->current_box; +uint8_t collision_displace(vec2d *desired_pos, + jumpnrun_moveable *current, + rectangle const *obstacle, + vec2d *inertia_mod) { + rectangle desired = current->hitbox; rectangle_move_to(&desired, *desired_pos); if(!rectangle_intersect(obstacle, &desired)) { - return; + return 0; } fixed_point x = FIXED_INT(1000), y = FIXED_INT(1000); fixed_point dx = desired_pos->x, dy = desired_pos->y; bool bottom_collision = false; + uint8_t coll_x = 0; + uint8_t coll_y = 0; + uint8_t coll = 0; + if(fixed_point_le(rectangle_top ( obstacle), rectangle_top(&desired)) && fixed_point_gt(rectangle_bottom( obstacle), rectangle_top(&desired)) && - fixed_point_lt(rectangle_top (&desired ), rectangle_top(¤t->current_box))) { + fixed_point_lt(rectangle_top (&desired ), rectangle_top(¤t->hitbox))) { - y = fixed_point_sub(rectangle_bottom(obstacle), rectangle_top(&desired)); - dy = rectangle_bottom(obstacle); + coll_y = JUMPNRUN_COLLISION_BOTTOM; + y = fixed_point_sub(rectangle_bottom(obstacle), rectangle_top(&desired)); + dy = rectangle_bottom(obstacle); } else if(fixed_point_gt(rectangle_bottom( obstacle), rectangle_bottom(&desired)) && - fixed_point_le(rectangle_top ( obstacle), rectangle_bottom(&desired)) && - fixed_point_gt(rectangle_top (&desired ), rectangle_top (¤t->current_box))) { + fixed_point_le(rectangle_top ( obstacle), rectangle_bottom(&desired)) && + fixed_point_gt(rectangle_top (&desired ), rectangle_top (¤t->hitbox))) { - y = fixed_point_sub(rectangle_bottom(&desired ), rectangle_top ( obstacle)); - dy = fixed_point_sub(rectangle_top ( obstacle), rectangle_height(&desired )); + coll_y = JUMPNRUN_COLLISION_TOP; + y = fixed_point_sub(rectangle_bottom(&desired ), rectangle_top ( obstacle)); + dy = fixed_point_sub(rectangle_top ( obstacle), rectangle_height(&desired )); bottom_collision = true; } - if(fixed_point_le(rectangle_left ( obstacle), rectangle_left(&desired)) && fixed_point_gt(rectangle_right( obstacle), rectangle_left(&desired)) && - fixed_point_lt(rectangle_left (&desired ), rectangle_left(¤t->current_box))) { + fixed_point_lt(rectangle_left (&desired ), rectangle_left(¤t->hitbox))) { - x = fixed_point_sub(rectangle_right(obstacle), rectangle_left(&desired)); - dx = rectangle_right(obstacle); + coll_x = JUMPNRUN_COLLISION_RIGHT; + x = fixed_point_sub(rectangle_right(obstacle), rectangle_left(&desired)); + dx = rectangle_right(obstacle); } else if(fixed_point_gt(rectangle_right( obstacle), rectangle_right(&desired)) && - fixed_point_le(rectangle_left ( obstacle), rectangle_right(&desired)) && - fixed_point_gt(rectangle_left (&desired ), rectangle_left (¤t->current_box))) { + fixed_point_le(rectangle_left ( obstacle), rectangle_right(&desired)) && + fixed_point_gt(rectangle_left (&desired ), rectangle_left (¤t->hitbox))) { - x = fixed_point_sub(rectangle_right(&desired ), rectangle_left ( obstacle)); - dx = fixed_point_sub(rectangle_left ( obstacle), rectangle_width(&desired )); + coll_x = JUMPNRUN_COLLISION_LEFT; + x = fixed_point_sub(rectangle_right(&desired ), rectangle_left ( obstacle)); + dx = fixed_point_sub(rectangle_left ( obstacle), rectangle_width(&desired )); } if(fixed_point_eq(x, y)) { desired_pos->x = dx; desired_pos->y = dy; + coll = coll_x | coll_y; } else if(fixed_point_gt(x, y)) { desired_pos->y = dy; inertia_mod->y = FIXED_INT(0); - current->touching_ground = bottom_collision; + if(bottom_collision) { + current->flags |= JUMPNRUN_MOVEABLE_TOUCHING_GROUND; + } else { + current->flags &= ~JUMPNRUN_MOVEABLE_TOUCHING_GROUND; + } + + coll = coll_y; } else { desired_pos->x = dx; inertia_mod->x = FIXED_INT(0); + coll = coll_x; } - return; + return coll; } -void collisions_tiles_displace(vec2d *desired_position, - jumpnrun_moveable *thing, - jumpnrun_level const *lv, - jumpnrun_tile_range const *visible_tiles, - vec2d *inertia_mod) +bool collisions_tiles_displace(vec2d *desired_position, + jumpnrun_moveable *thing, + jumpnrun_level const *lv, + jumpnrun_tile_range const *visible_tiles, + vec2d *inertia_mod) { int collision_tile[] = { -1, -1, -1, - -1, -1, -1, - -1, -1, -1 + -1, -1, -1, + -1, -1, -1 }; static int const collision_order[] = { 7, 1, 3, 5, 6, 8, 0, 2 }; - vec2d midpoint = rectangle_mid(&thing->current_box); + vec2d midpoint = rectangle_mid(&thing->hitbox); jumpnrun_tile_position midtile_pos = { fixed_point_cast_int(fixed_point_div(midpoint.x, FIXED_INT(JUMPNRUN_TILE_PIXEL_WIDTH ))), @@ -94,47 +109,54 @@ void collisions_tiles_displace(vec2d *desired_position, switch(xdiff) { case -1: - { - switch(ydiff) { - case -1: collision_tile[0] = tile; break; - case 0: collision_tile[1] = tile; break; - case 1: collision_tile[2] = tile; break; - } - break; + { + switch(ydiff) { + case -1: collision_tile[0] = tile; break; + case 0: collision_tile[1] = tile; break; + case 1: collision_tile[2] = tile; break; } + break; + } case 0: - { - switch(ydiff) { - case -1: collision_tile[3] = tile; break; - case 0: collision_tile[4] = tile; break; - case 1: collision_tile[5] = tile; break; - } - break; + { + switch(ydiff) { + case -1: collision_tile[3] = tile; break; + case 0: collision_tile[4] = tile; break; + case 1: collision_tile[5] = tile; break; } + break; + } case 1: - { - switch(ydiff) { - case -1: collision_tile[6] = tile; break; - case 0: collision_tile[7] = tile; break; - case 1: collision_tile[8] = tile; break; - } - break; + { + switch(ydiff) { + case -1: collision_tile[6] = tile; break; + case 0: collision_tile[7] = tile; break; + case 1: collision_tile[8] = tile; break; } + break; + } } } /* collision: sort by priority (top/bottom, left/right, then diagonal) */ - thing->touching_ground = false; + bool lethal = false; + thing->flags &= ~JUMPNRUN_MOVEABLE_TOUCHING_GROUND; for(size_t collision_index = 0; collision_index < ARRAY_SIZE(collision_order); ++collision_index) { if(collision_tile[collision_order[collision_index]] == -1) { continue; } - - rectangle tile_rect = rect_from_tile(&lv->tiles[collision_tile[collision_order[collision_index]]]); - collision_displace(desired_position, thing, &tile_rect, inertia_mod); + jumpnrun_tile *tile_obj = &lv->tiles[collision_tile[collision_order[collision_index]]]; + rectangle tile_rect = rect_from_tile(tile_obj); + + uint8_t coll = collision_displace(desired_position, thing, &tile_rect, inertia_mod); + if(coll & tile_type(tile_obj)->lethal_sides) { + lethal = true; + } } - rectangle_move_to(&thing->current_box, *desired_position); + rectangle_move_to(&thing->hitbox, *desired_position); + + return lethal; }