5 #include "rigid_rect.h"
6 #include "system/error.h"
9 #define RIGID_RECT_GRAVITY 1500.0f
21 static const vec_t opposing_rect_side_forces[RECT_SIDE_N] = {
22 { .x = 1.0f, .y = 0.0f }, /* RECT_SIDE_LEFT = 0, */
23 { .x = -1.0f, .y = 0.0f }, /* RECT_SIDE_RIGHT, */
24 { .x = 0.0f, .y = 1.0f, }, /* RECT_SIDE_TOP, */
25 { .x = 0.0f, .y = -1.0f, } /* RECT_SIDE_BOTTOM, */
28 static vec_t opposing_force_by_sides(int sides[RECT_SIDE_N])
30 vec_t opposing_force = {
35 for (rect_side_t side = 0; side < RECT_SIDE_N; ++side) {
39 opposing_rect_side_forces[side]);
43 return opposing_force;
46 rigid_rect_t *create_rigid_rect(rect_t rect, color_t color)
48 lt_t *lt = create_lt();
54 rigid_rect_t *rigid_rect = PUSH_LT(lt, malloc(sizeof(rigid_rect_t)), free);
55 if (rigid_rect == NULL) {
56 throw_error(ERROR_TYPE_LIBC);
61 rigid_rect->position = vec(rect.x, rect.y);
62 rigid_rect->velocity = vec(0.0f, 0.0f);
63 rigid_rect->movement = vec(0.0f, 0.0f);
64 rigid_rect->size = vec(rect.w, rect.h);
65 rigid_rect->color = color;
66 rigid_rect->touches_ground = 0;
71 void destroy_rigid_rect(rigid_rect_t *rigid_rect)
73 RETURN_LT0(rigid_rect->lt);
76 int rigid_rect_render(const rigid_rect_t *rigid_rect,
77 SDL_Renderer *renderer,
78 const camera_t *camera)
80 return camera_fill_rect(
83 rigid_rect_hitbox(rigid_rect),
88 int rigid_rect_update(rigid_rect_t * rigid_rect,
89 const platforms_t *platforms,
95 rigid_rect->touches_ground = 0;
97 rigid_rect->velocity.y += RIGID_RECT_GRAVITY * delta_time;
98 rigid_rect->position = vec_sum(
102 rigid_rect->velocity,
103 rigid_rect->movement),
106 int sides[RECT_SIDE_N] = { 0, 0, 0, 0 };
108 platforms_rect_object_collide(platforms, rigid_rect_hitbox(rigid_rect), sides);
110 if (sides[RECT_SIDE_BOTTOM]) {
111 rigid_rect->touches_ground = 1;
114 vec_t opposing_force = opposing_force_by_sides(sides);
116 for (int i = 0; i < 1000 && vec_length(opposing_force) > 1e-6; ++i) {
117 rigid_rect->position = vec_sum(
118 rigid_rect->position,
123 if (fabs(opposing_force.x) > 1e-6 && (opposing_force.x < 0.0f) != ((rigid_rect->velocity.x + rigid_rect->movement.x) < 0.0f)) {
124 rigid_rect->velocity.x = 0.0f;
125 rigid_rect->movement.x = 0.0f;
128 if (fabs(opposing_force.y) > 1e-6 && (opposing_force.y < 0.0f) != ((rigid_rect->velocity.y + rigid_rect->movement.y) < 0.0f)) {
129 rigid_rect->velocity.y = 0.0f;
130 rigid_rect->movement.y = 0.0f;
133 platforms_rect_object_collide(
135 rigid_rect_hitbox(rigid_rect),
137 opposing_force = opposing_force_by_sides(sides);
143 rect_t rigid_rect_hitbox(const rigid_rect_t *rigid_rect)
145 return rect_from_vecs(
146 rigid_rect->position,
150 void rigid_rect_move(rigid_rect_t *rigid_rect,
153 rigid_rect->movement = movement;
156 void rigid_rect_jump(rigid_rect_t *rigid_rect,
159 rigid_rect->velocity.y = -force;
162 int rigid_rect_touches_ground(const rigid_rect_t *rigid_rect)
164 return rigid_rect->touches_ground;