3 void collision_displace(vec2d
*desired_pos
,
4 jumpnrun_moveable
*current
,
5 rectangle
const *obstacle
,
7 rectangle desired
= current
->current_box
;
8 rectangle_move_to(&desired
, *desired_pos
);
10 if(!rectangle_intersect(obstacle
, &desired
)) {
14 fixed_point x
= FIXED_INT(1000), y
= FIXED_INT(1000);
15 fixed_point dx
= desired_pos
->x
, dy
= desired_pos
->y
;
16 bool bottom_collision
= false;
18 if(fixed_point_le(rectangle_top ( obstacle
), rectangle_top(&desired
)) &&
19 fixed_point_gt(rectangle_bottom( obstacle
), rectangle_top(&desired
)) &&
20 fixed_point_lt(rectangle_top (&desired
), rectangle_top(¤t
->current_box
))) {
22 y
= fixed_point_sub(rectangle_bottom(obstacle
), rectangle_top(&desired
));
23 dy
= rectangle_bottom(obstacle
);
25 } else if(fixed_point_gt(rectangle_bottom( obstacle
), rectangle_bottom(&desired
)) &&
26 fixed_point_le(rectangle_top ( obstacle
), rectangle_bottom(&desired
)) &&
27 fixed_point_gt(rectangle_top (&desired
), rectangle_top (¤t
->current_box
))) {
29 y
= fixed_point_sub(rectangle_bottom(&desired
), rectangle_top ( obstacle
));
30 dy
= fixed_point_sub(rectangle_top ( obstacle
), rectangle_height(&desired
));
31 bottom_collision
= true;
36 if(fixed_point_le(rectangle_left ( obstacle
), rectangle_left(&desired
)) &&
37 fixed_point_gt(rectangle_right( obstacle
), rectangle_left(&desired
)) &&
38 fixed_point_lt(rectangle_left (&desired
), rectangle_left(¤t
->current_box
))) {
40 x
= fixed_point_sub(rectangle_right(obstacle
), rectangle_left(&desired
));
41 dx
= rectangle_right(obstacle
);
43 } else if(fixed_point_gt(rectangle_right( obstacle
), rectangle_right(&desired
)) &&
44 fixed_point_le(rectangle_left ( obstacle
), rectangle_right(&desired
)) &&
45 fixed_point_gt(rectangle_left (&desired
), rectangle_left (¤t
->current_box
))) {
47 x
= fixed_point_sub(rectangle_right(&desired
), rectangle_left ( obstacle
));
48 dx
= fixed_point_sub(rectangle_left ( obstacle
), rectangle_width(&desired
));
52 if(fixed_point_eq(x
, y
)) {
55 } else if(fixed_point_gt(x
, y
)) {
57 inertia_mod
->y
= FIXED_INT(0);
59 current
->touching_ground
= bottom_collision
;
62 inertia_mod
->x
= FIXED_INT(0);
68 void collisions_tiles_displace(vec2d
*desired_position
,
69 jumpnrun_moveable
*thing
,
70 jumpnrun_level
const *lv
,
71 jumpnrun_tile_range
const *visible_tiles
,
74 int collision_tile
[] = { -1, -1, -1,
78 static int const collision_order
[] = { 7, 1, 3, 5, 6, 8, 0, 2 };
80 vec2d midpoint
= rectangle_mid(&thing
->current_box
);
82 jumpnrun_tile_position midtile_pos
= {
83 fixed_point_cast_int(fixed_point_div(midpoint
.x
, FIXED_INT(JUMPNRUN_TILE_PIXEL_WIDTH
))),
84 fixed_point_cast_int(fixed_point_div(midpoint
.y
, FIXED_INT(JUMPNRUN_TILE_PIXEL_HEIGHT
)))
89 for(tile
= visible_tiles
->first
; (size_t) tile
< visible_tiles
->last
&& lv
->tiles
[tile
].pos
.x
< midtile_pos
.x
- 1; ++tile
)
91 for(; (size_t) tile
< visible_tiles
->last
&& lv
->tiles
[tile
].pos
.x
< midtile_pos
.x
+ 2; ++tile
) {
92 int xdiff
= lv
->tiles
[tile
].pos
.x
- midtile_pos
.x
;
93 int ydiff
= lv
->tiles
[tile
].pos
.y
- midtile_pos
.y
;
99 case -1: collision_tile
[0] = tile
; break;
100 case 0: collision_tile
[1] = tile
; break;
101 case 1: collision_tile
[2] = tile
; break;
108 case -1: collision_tile
[3] = tile
; break;
109 case 0: collision_tile
[4] = tile
; break;
110 case 1: collision_tile
[5] = tile
; break;
117 case -1: collision_tile
[6] = tile
; break;
118 case 0: collision_tile
[7] = tile
; break;
119 case 1: collision_tile
[8] = tile
; break;
126 /* collision: sort by priority (top/bottom, left/right, then diagonal) */
127 thing
->touching_ground
= false;
129 for(size_t collision_index
= 0; collision_index
< ARRAY_SIZE(collision_order
); ++collision_index
) {
130 if(collision_tile
[collision_order
[collision_index
]] == -1) {
134 rectangle tile_rect
= rect_from_tile(&lv
->tiles
[collision_tile
[collision_order
[collision_index
]]]);
136 collision_displace(desired_position
, thing
, &tile_rect
, inertia_mod
);
139 rectangle_move_to(&thing
->current_box
, *desired_position
);