]> git.lizzy.rs Git - nothing.git/commitdiff
(#633) Migrate Player to RigidBodies
authorrexim <reximkut@gmail.com>
Sat, 16 Feb 2019 16:56:36 +0000 (23:56 +0700)
committerrexim <reximkut@gmail.com>
Sat, 16 Feb 2019 16:56:36 +0000 (23:56 +0700)
src/game/level.c
src/game/level/player.c
src/game/level/player.h
src/game/level/rigid_bodies.c
src/game/level/rigid_bodies.h
src/game/level/solid.c
src/game/level/solid.h

index 804d81c283970e46aaeb4fefa57a594f1eed6952..aecbe26a5aceab9304f89d54f823b1f7708df1c3 100644 (file)
@@ -30,6 +30,7 @@ struct Level
     Lt *lt;
 
     Background *background;
+    RigidBodies *rigid_bodies;
     Player *player;
     Platforms *platforms;
     Goals *goals;
@@ -39,7 +40,6 @@ struct Level
     Labels *labels;
     Regions *regions;
     Physical_world *physical_world;
-    RigidBodies *rigid_bodies;
 
     bool flying_mode;
     Vec flying_camera_position;
@@ -78,9 +78,14 @@ Level *create_level_from_file(const char *file_name, Broadcast *broadcast)
         RETURN_LT(lt, NULL);
     }
 
+    level->rigid_bodies = PUSH_LT(lt, create_rigid_bodies(1024), destroy_rigid_bodies);
+    if (level->rigid_bodies == NULL) {
+        RETURN_LT(lt, NULL);
+    }
+
     level->player = PUSH_LT(
         lt,
-        create_player_from_line_stream(level_stream, broadcast),
+        create_player_from_line_stream(level_stream, level->rigid_bodies, broadcast),
         destroy_player);
     if (level->player == NULL) {
         RETURN_LT(lt, NULL);
@@ -146,18 +151,10 @@ Level *create_level_from_file(const char *file_name, Broadcast *broadcast)
     if (level->physical_world == NULL) {
         RETURN_LT(lt, NULL);
     }
-    if (physical_world_add_solid(
-            level->physical_world,
-            player_as_solid(level->player)) < 0) { RETURN_LT(lt, NULL); }
     if (boxes_add_to_physical_world(
             level->boxes,
             level->physical_world) < 0) { RETURN_LT(lt, NULL); }
 
-    level->rigid_bodies = PUSH_LT(lt, create_rigid_bodies(1024), destroy_rigid_bodies);
-    if (level->rigid_bodies == NULL) {
-        RETURN_LT(lt, NULL);
-    }
-
     level->flying_mode = false;
     level->flying_camera_position = vec(0.0f, 0.0f);
     level->flying_camera_scale = 1.0f;
@@ -215,10 +212,6 @@ int level_render(const Level *level, Camera *camera)
         return -1;
     }
 
-    if (rigid_bodies_render(level->rigid_bodies, camera) < 0) {
-        return -1;
-    }
-
     return 0;
 }
 
@@ -231,7 +224,6 @@ int level_update(Level *level, float delta_time)
     boxes_float_in_lava(level->boxes, level->lava);
     rigid_bodies_apply_omniforce(level->rigid_bodies, vec(0.0f, LEVEL_GRAVITY));
 
-    rigid_bodies_update(level->rigid_bodies, delta_time);
     boxes_update(level->boxes, delta_time);
     player_update(level->player, delta_time);
 
@@ -341,7 +333,7 @@ int level_reload_preserve_player(Level *level, const char *file_name, Broadcast
     }
     level->background = RESET_LT(level->lt, level->background, background);
 
-    Player * const skipped_player = create_player_from_line_stream(level_stream, broadcast);
+    Player * const skipped_player = create_player_from_line_stream(level_stream, level->rigid_bodies, broadcast);
     if (skipped_player == NULL) {
         RETURN_LT(lt, -1);
     }
@@ -390,9 +382,6 @@ int level_reload_preserve_player(Level *level, const char *file_name, Broadcast
     level->regions = RESET_LT(level->lt, level->regions, regions);
 
     physical_world_clean(level->physical_world);
-    if (physical_world_add_solid(
-            level->physical_world,
-            player_as_solid(level->player)) < 0) { RETURN_LT(lt, -1); }
     if (boxes_add_to_physical_world(
             level->boxes,
             level->physical_world) < 0) { RETURN_LT(lt, -1); }
@@ -440,13 +429,7 @@ Rigid_rect *level_rigid_rect(Level *level,
     trace_assert(level);
     trace_assert(rigid_rect_id);
 
-    Rigid_rect *rigid_rect = player_rigid_rect(level->player,
-                                               rigid_rect_id);
-    if (rigid_rect != NULL) {
-        return rigid_rect;
-    }
-
-    rigid_rect = boxes_rigid_rect(level->boxes, rigid_rect_id);
+    Rigid_rect *rigid_rect = boxes_rigid_rect(level->boxes, rigid_rect_id);
     if (rigid_rect != NULL) {
         return rigid_rect;
     }
index c9e06d3ddb3040836003080bf0195e6a10cf2e49..7ecc473252a8eb5614880edda5b011bf461c0e50 100644 (file)
@@ -6,6 +6,7 @@
 #include "game/level/player/dying_rect.h"
 #include "game/level/player/rigid_rect.h"
 #include "game/level/script.h"
+#include "game/level/rigid_bodies.h"
 #include "goals.h"
 #include "math/point.h"
 #include "platforms.h"
@@ -32,7 +33,9 @@ struct Player {
     Lt *lt;
     Player_state state;
 
-    Rigid_rect *alive_body;
+    RigidBodies *rigid_bodies;
+
+    RigidBodyId alive_body_id;
     Dying_rect *dying_body;
     Script *script;
 
@@ -44,7 +47,7 @@ struct Player {
     int play_die_cue;
 };
 
-Player *create_player_from_line_stream(LineStream *line_stream, Broadcast *broadcast)
+Player *create_player_from_line_stream(LineStream *line_stream, RigidBodies *rigid_bodies, Broadcast *broadcast)
 {
     trace_assert(line_stream);
 
@@ -60,6 +63,8 @@ Player *create_player_from_line_stream(LineStream *line_stream, Broadcast *broad
     }
     player->lt = lt;
 
+    player->rigid_bodies = rigid_bodies;
+
     float x = 0.0f, y = 0.0f;
     char colorstr[7];
 
@@ -81,16 +86,10 @@ Player *create_player_from_line_stream(LineStream *line_stream, Broadcast *broad
 
     const Color color = hexstr(colorstr);
 
-    player->alive_body = PUSH_LT(
-        lt,
-        create_rigid_rect(
-            rect(x, y, PLAYER_WIDTH, PLAYER_HEIGHT),
-            color,
-            "player"),
-        destroy_rigid_rect);
-    if (player->alive_body == NULL) {
-        RETURN_LT(lt, NULL);
-    }
+    player->alive_body_id = rigid_bodies_add(
+        rigid_bodies,
+        rect(x, y, PLAYER_WIDTH, PLAYER_HEIGHT),
+        color);
 
     player->dying_body = PUSH_LT(
         lt,
@@ -116,25 +115,25 @@ void destroy_player(Player * player)
     RETURN_LT0(player->lt);
 }
 
-Solid_ref player_as_solid(Player *player)
-{
-    Solid_ref ref = {
-        .tag = SOLID_PLAYER,
-        .ptr = (void*) player
-    };
-
-    return ref;
-}
-
 int player_render(const Player * player,
                   Camera *camera)
 {
     trace_assert(player);
     trace_assert(camera);
 
+    char debug_text[256];
+
     switch (player->state) {
-    case PLAYER_STATE_ALIVE:
-        return rigid_rect_render(player->alive_body, camera);
+    case PLAYER_STATE_ALIVE: {
+        snprintf(debug_text, 256, "Jump: %d", player->jump_threshold);
+        Rect hitbox = rigid_bodies_hitbox(player->rigid_bodies, player->alive_body_id);
+
+        if (camera_render_debug_text(camera, debug_text, vec(hitbox.x, hitbox.y - 20.0f)) < 0) {
+            return -1;
+        }
+
+        return rigid_bodies_render(player->rigid_bodies, player->alive_body_id, camera);
+    }
 
     case PLAYER_STATE_DYING:
         return dying_rect_render(player->dying_body, camera);
@@ -152,9 +151,10 @@ void player_update(Player *player,
 
     switch (player->state) {
     case PLAYER_STATE_ALIVE: {
-        rigid_rect_update(player->alive_body, delta_time);
+        rigid_bodies_update(player->rigid_bodies, player->alive_body_id, delta_time);
+
+        const Rect hitbox = rigid_bodies_hitbox(player->rigid_bodies, player->alive_body_id);
 
-        const Rect hitbox = rigid_rect_hitbox(player->alive_body);
 
         if (hitbox.y > 1000.0f) {
             player_die(player);
@@ -165,12 +165,16 @@ void player_update(Player *player,
         dying_rect_update(player->dying_body, delta_time);
 
         if (dying_rect_is_dead(player->dying_body)) {
-            rigid_rect_transform_velocity(
-                player->alive_body,
+            rigid_bodies_transform_velocity(
+                player->rigid_bodies,
+                player->alive_body_id,
                 make_mat3x3(0.0f, 0.0f, 0.0f,
                             0.0f, 0.0f, 0.0f,
                             0.0f, 0.0f, 1.0f));
-            rigid_rect_teleport_to(player->alive_body, player->checkpoint);
+            rigid_bodies_teleport_to(
+                player->rigid_bodies,
+                player->alive_body_id,
+                player->checkpoint);
             player->state = PLAYER_STATE_ALIVE;
         }
     } break;
@@ -179,47 +183,45 @@ void player_update(Player *player,
     }
 }
 
-void player_collide_with_solid(Player *player, Solid_ref solid)
-{
-    if (player->state == PLAYER_STATE_ALIVE) {
-        rigid_rect_collide_with_solid(player->alive_body, solid);
-
-        if (rigid_rect_touches_ground(player->alive_body)) {
-            player->jump_threshold = 0;
-        }
-    }
-}
-
 void player_move_left(Player *player)
 {
     trace_assert(player);
-    rigid_rect_move(player->alive_body, vec(-PLAYER_SPEED, 0.0f));
+    rigid_bodies_move(player->rigid_bodies, player->alive_body_id, vec(-PLAYER_SPEED, 0.0f));
 }
 
 void player_move_right(Player *player)
 {
     trace_assert(player);
 
-    rigid_rect_move(player->alive_body, vec(PLAYER_SPEED, 0.0f));
+    rigid_bodies_move(player->rigid_bodies, player->alive_body_id, vec(PLAYER_SPEED, 0.0f));
 }
 
 void player_stop(Player *player)
 {
     trace_assert(player);
 
-    rigid_rect_move(player->alive_body, vec(0.0f, 0.0f));
+    rigid_bodies_move(player->rigid_bodies, player->alive_body_id, vec(0.0f, 0.0f));
 }
 
 void player_jump(Player *player)
 {
     trace_assert(player);
+
+    if (rigid_bodies_touches_ground(player->rigid_bodies, player->alive_body_id)) {
+        player->jump_threshold = 0;
+    }
+
     if (player->jump_threshold < PLAYER_MAX_JUMP_THRESHOLD) {
-        rigid_rect_transform_velocity(player->alive_body,
-                                      make_mat3x3(1.0f, 0.0f, 0.0f,
-                                                  0.0f, 0.0f, 0.0f,
-                                                  0.0f, 0.0f, 1.0f));
-        rigid_rect_apply_force(player->alive_body,
-                               vec(0.0f, -PLAYER_JUMP));
+        rigid_bodies_transform_velocity(
+            player->rigid_bodies,
+            player->alive_body_id,
+            make_mat3x3(1.0f, 0.0f, 0.0f,
+                        0.0f, 0.0f, 0.0f,
+                        0.0f, 0.0f, 1.0f));
+        rigid_bodies_apply_force(
+            player->rigid_bodies,
+            player->alive_body_id,
+            vec(0.0f, -PLAYER_JUMP));
         player->jump_threshold++;
 
         if (script_has_scope_value(player->script, "on-jump")) {
@@ -234,7 +236,9 @@ void player_die(Player *player)
 
     if (player->state == PLAYER_STATE_ALIVE) {
         const Rect hitbox =
-            rigid_rect_hitbox(player->alive_body);
+            rigid_bodies_hitbox(
+                player->rigid_bodies,
+                player->alive_body_id);
 
         player->play_die_cue = 1;
         dying_rect_start_dying(player->dying_body, vec(hitbox.x, hitbox.y));
@@ -248,7 +252,9 @@ void player_focus_camera(Player *player,
     trace_assert(player);
     trace_assert(camera);
 
-    const Rect player_hitbox = rigid_rect_hitbox(player->alive_body);
+    const Rect player_hitbox = rigid_bodies_hitbox(
+        player->rigid_bodies,
+        player->alive_body_id);
 
     camera_center_at(
         camera,
@@ -262,13 +268,21 @@ void player_hide_goals(const Player *player,
 {
     trace_assert(player);
     trace_assert(goals);
-    goals_hide_from_player(goals, rigid_rect_hitbox(player->alive_body));
+    goals_hide_from_player(
+        goals,
+        rigid_bodies_hitbox(
+            player->rigid_bodies,
+            player->alive_body_id));
 }
 
 void player_die_from_lava(Player *player,
                           const Lava *lava)
 {
-    if (lava_overlaps_rect(lava, rigid_rect_hitbox(player->alive_body))) {
+    if (lava_overlaps_rect(
+            lava,
+            rigid_bodies_hitbox(
+                player->rigid_bodies,
+                player->alive_body_id))) {
         player_die(player);
     }
 }
@@ -292,36 +306,6 @@ int player_sound(Player *player,
     return 0;
 }
 
-void player_touches_rect_sides(Player *player,
-                               Rect object,
-                               int sides[RECT_SIDE_N])
-{
-    if (player->state == PLAYER_STATE_ALIVE) {
-        rigid_rect_touches_rect_sides(player->alive_body, object, sides);
-    }
-}
-
-void player_apply_force(Player *player, Vec force)
-{
-    if (player->state == PLAYER_STATE_ALIVE) {
-        rigid_rect_apply_force(player->alive_body, force);
-    }
-}
-
-Rigid_rect *player_rigid_rect(Player *player, const char *id)
-{
-    trace_assert(player);
-    trace_assert(id);
-
-    if (player->state == PLAYER_STATE_ALIVE) {
-        if (rigid_rect_has_id(player->alive_body, id)) {
-            return player->alive_body;
-        }
-    }
-
-    return NULL;
-}
-
 bool player_overlaps_rect(const Player *player,
                           Rect rect)
 {
@@ -329,6 +313,7 @@ bool player_overlaps_rect(const Player *player,
 
     return player->state == PLAYER_STATE_ALIVE
         && rects_overlap(
-            rect, rigid_rect_hitbox(
-                player->alive_body));
+            rect, rigid_bodies_hitbox(
+                player->rigid_bodies,
+                player->alive_body_id));
 }
index e94786bb202e4e49dd4bcb14ed06feda34b21227..1c7aeda46d749d41a1f2e35b60eda55d4679b230 100644 (file)
@@ -15,8 +15,9 @@ typedef struct Rigid_rect Rigid_rect;
 typedef struct LineStream LineStream;
 typedef struct Script Script;
 typedef struct Broadcast Broadcast;
+typedef struct RigidBodies RigidBodies;
 
-Player *create_player_from_line_stream(LineStream *line_stream, Broadcast *broadcast);
+Player *create_player_from_line_stream(LineStream *line_stream, RigidBodies *rigid_bodies, Broadcast *broadcast);
 void destroy_player(Player * player);
 
 Solid_ref player_as_solid(Player *player);
index 8598e6db627152feedfef430e61b9c734743c71b..e4508500f93e65072805f14328bb7b7b0766aa55 100644 (file)
@@ -136,6 +136,9 @@ static int rigid_bodies_collide_with_platforms(
 int rigid_bodies_collide(RigidBodies *rigid_bodies,
                          const Platforms *platforms)
 {
+    // TODO: RigidBodies should collide only the bodies that were updated on after a previous collision
+    memset(rigid_bodies->grounded, 0, sizeof(bool) * rigid_bodies->count);
+
     if (rigid_bodies_collide_with_itself(rigid_bodies) < 0) {
         return -1;
     }
@@ -148,44 +151,38 @@ int rigid_bodies_collide(RigidBodies *rigid_bodies,
 }
 
 int rigid_bodies_update(RigidBodies *rigid_bodies,
+                        RigidBodyId id,
                         float delta_time)
 {
     trace_assert(rigid_bodies);
 
-    memset(rigid_bodies->grounded, 0,
-           sizeof(bool) * rigid_bodies->count);
-
-    for (size_t i = 0; i < rigid_bodies->count; ++i) {
-        rigid_bodies->velocities[i] = vec_sum(
-            rigid_bodies->velocities[i],
+    rigid_bodies->velocities[id] = vec_sum(
+            rigid_bodies->velocities[id],
             vec_scala_mult(
-                rigid_bodies->forces[i],
+                rigid_bodies->forces[id],
                 delta_time));
-    }
 
-    for (size_t i = 0; i < rigid_bodies->count; ++i) {
-        Vec position = vec(rigid_bodies->bodies[i].x,
-                           rigid_bodies->bodies[i].y);
+    Vec position = vec(rigid_bodies->bodies[id].x,
+                       rigid_bodies->bodies[id].y);
 
-        position = vec_sum(
-            position,
-            vec_scala_mult(
-                vec_sum(
-                    rigid_bodies->velocities[i],
-                    rigid_bodies->movements[i]),
-                delta_time));
+    position = vec_sum(
+        position,
+        vec_scala_mult(
+            vec_sum(
+                rigid_bodies->velocities[id],
+                rigid_bodies->movements[id]),
+            delta_time));
 
-        rigid_bodies->bodies[i].x = position.x;
-        rigid_bodies->bodies[i].y = position.y;
-    }
+    rigid_bodies->bodies[id].x = position.x;
+    rigid_bodies->bodies[id].y = position.y;
 
-    memset(rigid_bodies->forces, 0,
-           sizeof(Vec) * rigid_bodies->count);
+    rigid_bodies->forces[id] = vec(0.0f, 0.0f);
 
     return 0;
 }
 
 int rigid_bodies_render(RigidBodies *rigid_bodies,
+                        RigidBodyId id,
                         Camera *camera)
 {
     trace_assert(rigid_bodies);
@@ -193,34 +190,32 @@ int rigid_bodies_render(RigidBodies *rigid_bodies,
 
     char text_buffer[256];
 
-    for (size_t i = 0; i < rigid_bodies->count; ++i) {
-        if (camera_fill_rect(
-                camera,
-                rigid_bodies->bodies[i],
-                rigid_bodies->colors[i]) < 0) {
-            return -1;
-        }
+    if (camera_fill_rect(
+            camera,
+            rigid_bodies->bodies[id],
+            rigid_bodies->colors[id]) < 0) {
+        return -1;
+    }
 
-        snprintf(text_buffer, ID_SIZE, "%ld", i);
+    snprintf(text_buffer, ID_SIZE, "id: %ld", id);
 
-        if (camera_render_debug_text(
-                camera,
-                text_buffer,
-                vec(rigid_bodies->bodies[i].x,
-                    rigid_bodies->bodies[i].y)) < 0) {
-            return -1;
-        }
+    if (camera_render_debug_text(
+            camera,
+            text_buffer,
+            vec(rigid_bodies->bodies[id].x,
+                rigid_bodies->bodies[id].y)) < 0) {
+        return -1;
+    }
 
-        snprintf(text_buffer, 256, "(%f, %f)",
-                 rigid_bodies->bodies[i].x,
-                 rigid_bodies->bodies[i].y);
-        if (camera_render_debug_text(
-                camera,
-                text_buffer,
-                vec(rigid_bodies->bodies[i].x,
-                    rigid_bodies->bodies[i].y + FONT_CHAR_HEIGHT * 2.0f))) {
-            return -1;
-        }
+    snprintf(text_buffer, 256, "pos:(%f, %f)",
+             rigid_bodies->bodies[id].x,
+             rigid_bodies->bodies[id].y);
+    if (camera_render_debug_text(
+            camera,
+            text_buffer,
+            vec(rigid_bodies->bodies[id].x,
+                rigid_bodies->bodies[id].y + FONT_CHAR_HEIGHT * 2.0f))) {
+        return -1;
     }
 
     return 0;
index 1fb2c642cc4d1a08b16412a1ffea956665e353c1..da2458837df451c981d407a74e19800a19bbee68 100644 (file)
@@ -14,9 +14,11 @@ int rigid_bodies_collide(RigidBodies *rigid_bodies,
                          const Platforms *platforms);
 
 int rigid_bodies_update(RigidBodies *rigid_bodies,
+                        RigidBodyId id,
                         float delta_time);
 
 int rigid_bodies_render(RigidBodies *rigid_bodies,
+                        RigidBodyId id,
                         Camera *camera);
 RigidBodyId rigid_bodies_add(RigidBodies *rigid_bodies,
                              Rect rect,
index f9db14da8f526edade75cedb8d33ae0070229455..bf9564dfa2f35ca50c5fc467f423e9e3d80c1d8c 100644 (file)
@@ -16,10 +16,6 @@ void solid_touches_rect_sides(Solid_ref solid,
     case SOLID_RIGID_RECT:
         rigid_rect_touches_rect_sides((Rigid_rect *) solid.ptr, object, sides);
         break;
-
-    case SOLID_PLAYER:
-        player_touches_rect_sides((Player *) solid.ptr, object, sides);
-        break;
     }
 }
 
@@ -35,10 +31,6 @@ void solid_apply_force(Solid_ref solid,
         rigid_rect_apply_force((Rigid_rect *) solid.ptr, force);
         break;
 
-    case SOLID_PLAYER:
-        player_apply_force((Player *) solid.ptr, force);
-        break;
-
     default: {}
     }
 }
@@ -55,10 +47,6 @@ void solid_collide_with_solid(Solid_ref solid,
         rigid_rect_collide_with_solid((Rigid_rect *) solid.ptr, other_solid);
         break;
 
-    case SOLID_PLAYER:
-        player_collide_with_solid((Player *) solid.ptr, other_solid);
-        break;
-
     default: {}
     }
 }
index 444b7e04b166665880eb558ebcbac34e60b04c06..5b256d72b2d9727e3e3655ac9305d21e4587da33 100644 (file)
@@ -7,8 +7,7 @@
 
 typedef enum Solid_tag {
     SOLID_PLATFORMS = 0,
-    SOLID_RIGID_RECT,
-    SOLID_PLAYER
+    SOLID_RIGID_RECT
 } Solid_tag;
 
 typedef struct Solid_ref {