]> git.lizzy.rs Git - nothing.git/commitdiff
(#189) Fix standing on the boxes
authorrexim <reximkut@gmail.com>
Sat, 19 May 2018 17:20:27 +0000 (00:20 +0700)
committerrexim <reximkut@gmail.com>
Sat, 19 May 2018 17:20:27 +0000 (00:20 +0700)
src/game/level.c
src/game/level/boxes.c
src/game/level/boxes.h
src/game/level/player.c
src/game/level/player.h
src/game/level/player/rigid_rect.c
src/game/level/player/rigid_rect.h

index 77d6c2e68360d99ea4f12bb5b44f22aedbf91a25..587c2a6097253f31f4a3c3964960ea16ccfde6e5 100644 (file)
@@ -156,11 +156,13 @@ int level_update(level_t *level, float delta_time)
     assert(delta_time > 0);
 
     player_update(level->player, delta_time);
-    player_collide_with_platforms(level->player, level->platforms);
 
     boxes_update(level->boxes, delta_time);
-    boxes_collide_with_player(level->boxes, level->player);
     boxes_collide_with_platforms(level->boxes, level->platforms);
+    boxes_collide_with_player(level->boxes, level->player);
+
+    player_collide_with_platforms(level->player, level->platforms);
+    player_collide_with_boxes(level->player, level->boxes);
 
     player_hide_goals(level->player, level->goals);
     player_die_from_lava(level->player, level->lava);
index 941b9e00ba5c523c417828db2451c0d609275d72..417c339ecb0a58f30a3be82f6a130ab681a0e1be 100644 (file)
@@ -1,6 +1,7 @@
 #include <assert.h>
 
 #include "game/level/boxes.h"
+#include "game/level/player.h"
 #include "game/level/player/rigid_rect.h"
 #include "system/lt.h"
 #include "system/error.h"
@@ -116,10 +117,21 @@ void boxes_collide_with_player(boxes_t *boxes,
     assert(boxes);
     assert(player);
 
-    const rect_t hitbox = player_hitbox(player);
+    for (size_t i = 0; i < boxes->count; ++i) {
+        player_impact_rigid_rect(player, boxes->bodies[i]);
+    }
+}
+
+void boxes_rect_object_collide(const boxes_t *boxes,
+                               rect_t object,
+                               int sides[RECT_SIDE_N])
+{
+    assert(boxes);
+
+    memset(sides, 0, sizeof(int) * RECT_SIDE_N);
 
     for (size_t i = 0; i < boxes->count; ++i) {
-        player_collide_with_rect(player, rigid_rect_hitbox(boxes->bodies[i]));
-        rigid_rect_collide_with_rect(boxes->bodies[i], hitbox);
+        const rect_t hitbox = rigid_rect_hitbox(boxes->bodies[i]);
+        rect_object_impact(&object, &hitbox, sides);
     }
 }
index e0cde02d4e9b147e2cea33ec9ae41bdf8b8fabe3..bf11b9b30c00d281831b10dc5a61a4f4bc16c13b 100644 (file)
@@ -2,16 +2,19 @@
 #define BOXES_H_
 
 #include "game/level/platforms.h"
-#include "game/level/player.h"
 #include "game/camera.h"
 
 typedef struct boxes_t boxes_t;
+typedef struct player_t player_t;
 
 boxes_t *create_boxes_from_stream(FILE *stream);
 void destroy_boxes(boxes_t *boxes);
 
 int boxes_render(boxes_t *boxes, camera_t *camera);
 int boxes_update(boxes_t *boxes, float delta_time);
+void boxes_rect_object_collide(const boxes_t *boxes,
+                               rect_t object,
+                               int sides[RECT_SIDE_N]);
 void boxes_collide_with_platforms(boxes_t *boxes,
                                   const platforms_t *platforms);
 void boxes_collide_with_player(boxes_t *boxes,
index fa8324a8b99127911404e4035077963905bd5b45..f63a919af5a0575c90112ad60dfe070ae830c0fd 100644 (file)
@@ -170,6 +170,18 @@ void player_collide_with_platforms(player_t * player,
     }
 }
 
+void player_collide_with_boxes(player_t * player,
+                               const boxes_t * boxes)
+{
+    if (player->state == PLAYER_STATE_ALIVE) {
+        rigid_rect_collide_with_boxes(player->alive_body, boxes);
+
+        if (rigid_rect_touches_ground(player->alive_body)) {
+            player->jump_count = 0;
+        }
+    }
+}
+
 void player_collide_with_rect(player_t * player,
                               rect_t rect)
 {
@@ -182,6 +194,14 @@ void player_collide_with_rect(player_t * player,
     }
 }
 
+void player_impact_rigid_rect(player_t * player,
+                              rigid_rect_t *rigid_rect)
+{
+    if (player->state == PLAYER_STATE_ALIVE) {
+        rigid_rect_impact_rigid_rect(player->alive_body, rigid_rect);
+    }
+}
+
 void player_move_left(player_t *player)
 {
     assert(player);
index 97cc549cbe19eb2ba37a1e009633fff33b5ee461..28863e252c231d00f1fd5a70ae6a3b09cc1758f3 100644 (file)
@@ -7,10 +7,11 @@
 #include "game/sound_samples.h"
 #include "lava.h"
 #include "platforms.h"
+#include "boxes.h"
 
 typedef struct player_t player_t;
-
 typedef struct goals_t goals_t;
+typedef struct rigid_rect_t rigid_rect_t;
 
 player_t *create_player(float x, float y, color_t color);
 player_t *create_player_from_stream(FILE *stream);
@@ -24,6 +25,10 @@ void player_collide_with_platforms(player_t * player,
                                    const platforms_t *platforms);
 void player_collide_with_rect(player_t * player,
                               rect_t rect);
+void player_collide_with_boxes(player_t * player,
+                               const boxes_t * boxes);
+void player_impact_rigid_rect(player_t * player,
+                              rigid_rect_t *rigid_rect);
 
 rect_t player_hitbox(const player_t *player);
 
index 8b687713bfd4b5c69bcf5c247a53bf169d9db726..b1097c04d195e374f2351bfb46e3c8c3f56f0f53 100644 (file)
@@ -6,6 +6,7 @@
 #include "rigid_rect.h"
 #include "system/error.h"
 #include "system/lt.h"
+#include "game/level/boxes.h"
 
 #define RIGID_RECT_GRAVITY 1500.0f
 
@@ -195,6 +196,55 @@ void rigid_rect_collide_with_rect(rigid_rect_t * rigid_rect,
     }
 }
 
+void rigid_rect_collide_with_boxes(rigid_rect_t * rigid_rect,
+                                   const boxes_t *boxes)
+{
+    int sides[RECT_SIDE_N] = { 0, 0, 0, 0 };
+
+    boxes_rect_object_collide(boxes, rigid_rect_hitbox(rigid_rect), sides);
+
+    if (sides[RECT_SIDE_BOTTOM]) {
+        rigid_rect->touches_ground = 1;
+    }
+
+    vec_t opposing_force = opposing_force_by_sides(sides);
+
+    for (int i = 0; i < 1000 && vec_length(opposing_force) > 1e-6; ++i) {
+        rigid_rect->position = vec_sum(
+            rigid_rect->position,
+            vec_scala_mult(
+                opposing_force,
+                1e-2f));
+
+        if (fabs(opposing_force.x) > 1e-6 && (opposing_force.x < 0.0f) != ((rigid_rect->velocity.x + rigid_rect->movement.x) < 0.0f)) {
+            rigid_rect->velocity.x = 0.0f;
+            rigid_rect->movement.x = 0.0f;
+        }
+
+        if (fabs(opposing_force.y) > 1e-6 && (opposing_force.y < 0.0f) != ((rigid_rect->velocity.y + rigid_rect->movement.y) < 0.0f)) {
+            rigid_rect->velocity.y = 0.0f;
+            rigid_rect->movement.y = 0.0f;
+        }
+
+        boxes_rect_object_collide(
+            boxes,
+            rigid_rect_hitbox(rigid_rect),
+            sides);
+        opposing_force = opposing_force_by_sides(sides);
+    }
+}
+
+void rigid_rect_impact_rigid_rect(rigid_rect_t * rigid_rect,
+                                 rigid_rect_t *another_rect)
+{
+    if (rects_overlap(rigid_rect_hitbox(rigid_rect), rigid_rect_hitbox(another_rect))) {
+        rigid_rect_move(another_rect,
+                        vec_sum(
+                            rigid_rect->velocity,
+                            rigid_rect->movement));
+    }
+}
+
 rect_t rigid_rect_hitbox(const rigid_rect_t *rigid_rect)
 {
     return rect_from_vecs(
index 1d9309a1ac00991cd8791eab8be8c439b0fb5ac6..ba46b5eed3afefffe40ea8e8c9fc1f727c9baff7 100644 (file)
@@ -7,6 +7,7 @@
 #include "math/rect.h"
 
 typedef struct rigid_rect_t rigid_rect_t;
+typedef struct boxes_t boxes_t;
 
 rigid_rect_t *create_rigid_rect(rect_t rect, color_t color);
 rigid_rect_t *create_rigid_rect_from_stream(FILE *stream);
@@ -21,6 +22,10 @@ void rigid_rect_collide_with_platforms(rigid_rect_t * rigid_rect,
                                        const platforms_t *platforms);
 void rigid_rect_collide_with_rect(rigid_rect_t * rigid_rect,
                                   rect_t rect);
+void rigid_rect_collide_with_boxes(rigid_rect_t * rigid_rect,
+                                   const boxes_t *boxes);
+void rigid_rect_impact_rigid_rect(rigid_rect_t * rigid_rect,
+                                  rigid_rect_t *another_rect);
 
 rect_t rigid_rect_hitbox(const rigid_rect_t *rigid_rect);