]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/player.c
(#207) Remove wavy_rect_overlaps
[nothing.git] / src / game / level / player.c
index 3737be6c6cd0383009434f3a8febe12f12d923d6..c27ae951ecc44c49160b93fa09e98b047f8ed16c 100644 (file)
@@ -15,8 +15,9 @@
 #define PLAYER_WIDTH 25.0f
 #define PLAYER_HEIGHT 25.0f
 #define PLAYER_SPEED 500.0f
-#define PLAYER_JUMP 550.0f
+#define PLAYER_JUMP 32000.0f
 #define PLAYER_DEATH_DURATION 0.75f
+#define PLAYER_MAX_JUMP_COUNT 2
 
 typedef enum player_state_t {
     PLAYER_STATE_ALIVE = 0,
@@ -33,8 +34,9 @@ struct player_t {
     int jump_count;
     color_t color;
 
-    /* TODO(#110): introduce checkpoints */
     vec_t checkpoint;
+
+    int play_die_cue;
 };
 
 player_t *create_player(float x, float y, color_t color)
@@ -66,7 +68,6 @@ player_t *create_player(float x, float y, color_t color)
     player->dying_body = PUSH_LT(
         lt,
         create_dying_rect(
-            rect(x, y, PLAYER_WIDTH, PLAYER_HEIGHT),
             color,
             PLAYER_DEATH_DURATION),
         destroy_dying_rect);
@@ -78,6 +79,7 @@ player_t *create_player(float x, float y, color_t color)
     player->jump_count = 0;
     player->color = color;
     player->checkpoint = vec(x, y);
+    player->play_die_cue = 0;
 
     return player;
 }
@@ -100,20 +102,28 @@ void destroy_player(player_t * player)
     RETURN_LT0(player->lt);
 }
 
+solid_ref_t player_as_solid(player_t *player)
+{
+    solid_ref_t ref = {
+        .tag = SOLID_PLAYER,
+        .ptr = (void*) player
+    };
+
+    return ref;
+}
+
 int player_render(const player_t * player,
-                  SDL_Renderer *renderer,
-                  const camera_t *camera)
+                  camera_t *camera)
 {
     assert(player);
-    assert(renderer);
     assert(camera);
 
     switch (player->state) {
     case PLAYER_STATE_ALIVE:
-        return rigid_rect_render(player->alive_body, renderer, camera);
+        return rigid_rect_render(player->alive_body, camera);
 
     case PLAYER_STATE_DYING:
-        return dying_rect_render(player->dying_body, renderer, camera);
+        return dying_rect_render(player->dying_body, camera);
 
     default: {}
     }
@@ -122,19 +132,13 @@ int player_render(const player_t * player,
 }
 
 void player_update(player_t *player,
-                   const platforms_t *platforms,
                    float delta_time)
 {
     assert(player);
-    assert(platforms);
 
     switch (player->state) {
     case PLAYER_STATE_ALIVE: {
-        rigid_rect_update(player->alive_body, platforms, delta_time);
-
-        if (rigid_rect_touches_ground(player->alive_body)) {
-            player->jump_count = 0;
-        }
+        rigid_rect_update(player->alive_body, delta_time);
 
         const rect_t hitbox = rigid_rect_hitbox(player->alive_body);
 
@@ -147,14 +151,12 @@ void player_update(player_t *player,
         dying_rect_update(player->dying_body, delta_time);
 
         if (dying_rect_is_dead(player->dying_body)) {
-            player->alive_body = RESET_LT(
-                player->lt,
+            rigid_rect_transform_velocity(
                 player->alive_body,
-                create_rigid_rect(
-                    rect_from_vecs(
-                        player->checkpoint,
-                        vec(PLAYER_WIDTH, PLAYER_HEIGHT)),
-                    player->color));
+                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);
             player->state = PLAYER_STATE_ALIVE;
         }
     } break;
@@ -163,6 +165,17 @@ void player_update(player_t *player,
     }
 }
 
+void player_collide_with_solid(player_t *player, solid_ref_t 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_count = 0;
+        }
+    }
+}
+
 void player_move_left(player_t *player)
 {
     assert(player);
@@ -186,8 +199,13 @@ void player_stop(player_t *player)
 void player_jump(player_t *player)
 {
     assert(player);
-    if (player->jump_count < 2) {
-        rigid_rect_jump(player->alive_body, PLAYER_JUMP);
+    if (player->jump_count < PLAYER_MAX_JUMP_COUNT) {
+        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));
         player->jump_count++;
     }
 }
@@ -197,13 +215,11 @@ void player_die(player_t *player)
     assert(player);
 
     if (player->state == PLAYER_STATE_ALIVE) {
-        player->dying_body = RESET_LT(
-            player->lt,
-            player->dying_body,
-            create_dying_rect(
-                rigid_rect_hitbox(player->alive_body),
-                player->color,
-                PLAYER_DEATH_DURATION));
+        const rect_t hitbox =
+            rigid_rect_hitbox(player->alive_body);
+
+        player->play_die_cue = 1;
+        dying_rect_start_dying(player->dying_body, vec(hitbox.x, hitbox.y));
         player->state = PLAYER_STATE_DYING;
     }
 }
@@ -243,3 +259,33 @@ void player_checkpoint(player_t *player, vec_t checkpoint)
 {
     player->checkpoint = checkpoint;
 }
+
+int player_sound(player_t *player,
+                 sound_samples_t *sound_samples)
+{
+    if (player->play_die_cue) {
+        player->play_die_cue = 0;
+
+        if (sound_samples_play_sound(sound_samples, 0, 0) < 0) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+void player_touches_rect_sides(player_t *player,
+                               rect_t 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_t *player, vec_t force)
+{
+    if (player->state == PLAYER_STATE_ALIVE) {
+        rigid_rect_apply_force(player->alive_body, force);
+    }
+}