From ae730ce029914c45e16dbb5ca13d4356e45ff52e Mon Sep 17 00:00:00 2001 From: En Yi Date: Sat, 7 Oct 2023 22:35:15 +0800 Subject: [PATCH] Finish initial camera behaviour x follows a mass-spring-damper system y is simple lerp. Doesnt follow player when jumping --- scenes/game_systems.c | 82 +++++++++++++------------------------------ scenes/scene_impl.h | 1 + 2 files changed, 25 insertions(+), 58 deletions(-) diff --git a/scenes/game_systems.c b/scenes/game_systems.c index 1917415..0ebdc6a 100644 --- a/scenes/game_systems.c +++ b/scenes/game_systems.c @@ -1801,69 +1801,47 @@ void camera_update_system(Scene_t* scene) const int height =data->game_rec.height; data->camera.cam.offset = (Vector2){ width/2.0f, height/2.0f }; - Vector2 target_pos = {0, data->camera.cam.target.y}; Vector2 target_vel = {0}; sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) { CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T); - target_pos.x = p_ctransform->position.x; + data->camera.target_pos.x = p_ctransform->position.x; target_vel = p_ctransform->velocity; CMovementState_t* p_movement = get_component(p_player, CMOVEMENTSTATE_T); - target_pos.x += (p_movement->x_dir == 1) ? width/6: -width/6; - //target_pos.y += p_ctransform->velocity.y * 0.08; + CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T); + data->camera.target_pos.x += (p_movement->x_dir == 1) ? width/6: -width/6; - //else if (p_ctransform->velocity.y > 0) + if (p_movement->ground_state == 0b01 + || (p_movement->water_state & 1) + || (p_pstate->ladder_state & 1) + ) { - //target_pos.y = p_ctransform->position.y; - target_pos.y = p_ctransform->position.y + Clamp(p_ctransform->velocity.y * 0.1, -height/6, height /6); + data->camera.base_y = p_ctransform->position.y; } - - if (p_movement->ground_state & 1) + if (p_ctransform->position.y >= data->camera.base_y) { - target_pos.y -= height / 8; + data->camera.target_pos.y = p_ctransform->position.y; } } - //target_pos.x = Clamp(target_pos.x, 0, - // fmax(data->tilemap.width * TILE_SIZE, data->game_rec.width)); + data->camera.target_pos.x = Clamp(data->camera.target_pos.x, data->game_rec.width / 2, + fmax(data->tilemap.width * TILE_SIZE, data->game_rec.width) - data->game_rec.width / 2); + data->camera.target_pos.y = Clamp(data->camera.target_pos.y, data->game_rec.height / 2, + fmax(data->tilemap.height * TILE_SIZE, data->game_rec.width) - data->game_rec.height / 2); // Mass-Spring damper update in x direction - //float x = target_pos.x - data->camera.cam.target.x; - //float v = data->camera.current_vel.x - target_vel.x; - //float F = data->camera.k * x - data->camera.c * v; - //// Kinematics update - //const float dt = DELTA_T; - //float a_dt = F * dt / data->camera.mass; - //data->camera.cam.target.x += (data->camera.current_vel.x + a_dt * 0.5) * dt; - - //data->camera.current_vel.x += a_dt; - - //// Simple lerp for y direction - //float dy = target_pos.y - data->camera.cam.target.y; - //data->camera.cam.target.y += dy * (dy < 0 ? 0.01 : 0.2); - - // Mass-Spring damper update - Vector2 x = Vector2Subtract(target_pos, data->camera.cam.target); - Vector2 v = Vector2Subtract(data->camera.current_vel, target_vel); - //Vector2 v = data->camera.current_vel; - Vector2 F = - Vector2Subtract( - Vector2Scale(x, data->camera.k), - Vector2Scale(v, data->camera.c) - ); - + float x = data->camera.target_pos.x - data->camera.cam.target.x; + float v = data->camera.current_vel.x - target_vel.x; + float F = data->camera.k * x - data->camera.c * v; // Kinematics update const float dt = DELTA_T; - Vector2 a_dt = Vector2Scale(F, dt/data->camera.mass); - data->camera.cam.target = - Vector2Add( - data->camera.cam.target, - Vector2Add( - Vector2Scale(data->camera.current_vel, dt), - Vector2Scale(a_dt, dt*0.5f) - ) - ); - data->camera.current_vel = Vector2Add(data->camera.current_vel, a_dt); + float a_dt = F * dt / data->camera.mass; + data->camera.cam.target.x += (data->camera.current_vel.x + a_dt * 0.5) * dt; + data->camera.current_vel.x += a_dt; + + // Simple lerp for y direction + float dy = data->camera.target_pos.y - data->camera.cam.target.y; + data->camera.cam.target.y += dy * 0.1; Vector2 max = GetWorldToScreen2D( (Vector2){ @@ -1887,18 +1865,6 @@ void camera_update_system(Scene_t* scene) data->camera.current_vel.x = 0; } - if (max.y < height) - { - data->camera.cam.offset.y = height - (max.y - height/2.0f); - data->camera.cam.target.y = fmax(data->tilemap.height * TILE_SIZE, data->game_rec.height) - height / 2; - data->camera.current_vel.y = 0; - } - if (min.y > 0) - { - data->camera.cam.offset.y = height/2.0f - min.y; - data->camera.cam.target.y = height / 2; - data->camera.current_vel.y = 0; - } } void level_end_detection_system(Scene_t* scene) diff --git a/scenes/scene_impl.h b/scenes/scene_impl.h index e5fb873..a13e964 100644 --- a/scenes/scene_impl.h +++ b/scenes/scene_impl.h @@ -30,6 +30,7 @@ typedef struct CoinCounter typedef struct LevelCamera { Camera2D cam; Vector2 target_pos; + float base_y; //Vector2 prev_pos; Vector2 current_vel; float mass;