fp: Simplify camera shake, don't modify main camera, square & cube intensity
This commit is contained in:
		
							parent
							
								
									4158674031
								
							
						
					
					
						commit
						49c80e60e8
					
				@ -1995,26 +1995,8 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (entity->flags & FP_GameEntityFlag_CameraTracking) {
 | 
			
		||||
                    FP_GameCamera *camera    = &game->play.camera;
 | 
			
		||||
 | 
			
		||||
                    // NOTE: calculate camera position based on camera shake
 | 
			
		||||
                    Dqn_V2 camera_position = camera->world_pos;
 | 
			
		||||
                    if (camera->shake_duration > 0) {
 | 
			
		||||
                        Dqn_f32 offset_x = (Dqn_PCG32_NextF32(&game->play.rng) * 1000 - 500) * camera->shake_intensity;
 | 
			
		||||
                        Dqn_f32 offset_y = (Dqn_PCG32_NextF32(&game->play.rng) * 1000 - 500) * camera->shake_intensity;
 | 
			
		||||
 | 
			
		||||
                        camera_position.x += offset_x;
 | 
			
		||||
                        camera_position.y += offset_y;
 | 
			
		||||
 | 
			
		||||
                        camera->shake_duration -= input->delta_s;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Dqn_f64 camera_smoothing = 5.0f;
 | 
			
		||||
 | 
			
		||||
                    camera->world_pos.x += (camera_position.x - camera->world_pos.x) * (camera_smoothing * input->delta_s);
 | 
			
		||||
                    camera->world_pos.y += (camera_position.y - camera->world_pos.y) * (camera_smoothing * input->delta_s);
 | 
			
		||||
 | 
			
		||||
                    camera->world_pos_target = FP_Game_CalcEntityWorldPos(game, entity->handle) * camera->scale;
 | 
			
		||||
                    game->play.camera_tracking_entity  = entity->handle;
 | 
			
		||||
                    game->play.camera.world_pos_target = FP_Game_CalcEntityWorldPos(game, entity->handle) * game->play.camera.scale;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                FP_GamePlaceableBuilding placeable_building = PLACEABLE_BUILDINGS[game->play.build_mode_building_index];
 | 
			
		||||
@ -2149,6 +2131,8 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        entity->trauma01 = DQN_MAX(0.f, entity->trauma01 - 0.05f);
 | 
			
		||||
 | 
			
		||||
        // NOTE: Derive dynmamic bounding boxes ====================================================
 | 
			
		||||
        if (entity->flags & FP_GameEntityFlag_DeriveHitBoxFromChildrenBoundingBox) {
 | 
			
		||||
            Dqn_Rect children_bbox = {};
 | 
			
		||||
@ -2263,12 +2247,8 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                defender->hp              = defender->hp >= attacker->base_attack ? defender->hp - attacker->base_attack : 0;
 | 
			
		||||
                defender->hit_on_frame = game->play.update_counter;
 | 
			
		||||
 | 
			
		||||
                if (game->play.player == defender->handle) {
 | 
			
		||||
                    game->play.camera.shake_intensity = 0.1f;
 | 
			
		||||
                    game->play.camera.shake_duration  = 0.25f;
 | 
			
		||||
                }
 | 
			
		||||
                defender->hit_on_clock_ms = game->play.update_counter;
 | 
			
		||||
                defender->trauma01        = 1.f - (defender->hp / DQN_CAST(Dqn_f32)defender->hp_cap);
 | 
			
		||||
 | 
			
		||||
                if (defender->hp <= 0) {
 | 
			
		||||
                    if (!defender->is_dying) {
 | 
			
		||||
@ -2352,7 +2332,29 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
 | 
			
		||||
    TELY_RFui_PushFont(rfui, game->jetbrains_mono_font);
 | 
			
		||||
    TELY_RFui_PushLabelColourV4(rfui, TELY_COLOUR_BLACK_MIDNIGHT_V4);
 | 
			
		||||
 | 
			
		||||
    FP_GameCameraM2x3 camera_xforms = FP_Game_CameraModelViewM2x3(game->play.camera);
 | 
			
		||||
    FP_GameCamera shake_camera = game->play.camera;
 | 
			
		||||
    {
 | 
			
		||||
        // NOTE: Calculate camera position based on camera shake
 | 
			
		||||
        FP_GameEntity *camera_entity = FP_Game_GetEntity(game, game->play.camera_tracking_entity);
 | 
			
		||||
        Dqn_f32        trauma01      = DQN_SQUARED(camera_entity->trauma01);
 | 
			
		||||
 | 
			
		||||
        if (camera_entity->type == FP_EntityType_Terry) {
 | 
			
		||||
            // NOTE: The heart shake is trauma^3 to emphasise the severity of losing heart health
 | 
			
		||||
            FP_GameEntity *heart = FP_Game_GetEntity(game, game->play.heart);
 | 
			
		||||
            trauma01             = DQN_MAX(trauma01, DQN_SQUARED(heart->trauma01) * heart->trauma01);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Dqn_f32 max_shake_dist  = 400.f;
 | 
			
		||||
        Dqn_f32 half_shake_dist = max_shake_dist * .5f;
 | 
			
		||||
        Dqn_V2  shake_offset    = {};
 | 
			
		||||
        shake_offset.x          = (Dqn_PCG32_NextF32(&game->play.rng) * max_shake_dist - half_shake_dist) * trauma01;
 | 
			
		||||
        shake_offset.y          = (Dqn_PCG32_NextF32(&game->play.rng) * max_shake_dist - half_shake_dist) * trauma01;
 | 
			
		||||
 | 
			
		||||
        Dqn_f32 interp_rate = 5.0f * DQN_CAST(Dqn_f32)input->delta_s;
 | 
			
		||||
        shake_camera.world_pos += shake_offset * interp_rate;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FP_GameCameraM2x3 camera_xforms = FP_Game_CameraModelViewM2x3(shake_camera);
 | 
			
		||||
    TELY_Render_PushTransform(renderer, camera_xforms.model_view);
 | 
			
		||||
    Dqn_V2 world_mouse_p = Dqn_M2x3_MulV2(camera_xforms.view_model, input->mouse_p);
 | 
			
		||||
 | 
			
		||||
@ -2459,14 +2461,14 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
 | 
			
		||||
                dest_rect.size.h *= -1.f; // NOTE: Flip the texture vertically
 | 
			
		||||
 | 
			
		||||
            Dqn_V4 sprite_colour = TELY_COLOUR_WHITE_V4;
 | 
			
		||||
            if (entity->hit_on_frame) {
 | 
			
		||||
                DQN_ASSERT(game->play.update_counter >= entity->hit_on_frame);
 | 
			
		||||
                Dqn_usize       frames_elapsed_since_hit = game->play.update_counter - entity->hit_on_frame;
 | 
			
		||||
                Dqn_usize const HIT_CONFIRM_DURATION     = 8;
 | 
			
		||||
                if (frames_elapsed_since_hit < HIT_CONFIRM_DURATION) {
 | 
			
		||||
            if (entity->hit_on_clock_ms) {
 | 
			
		||||
                DQN_ASSERT(game->play.clock_ms >= entity->hit_on_clock_ms);
 | 
			
		||||
                Dqn_usize       ms_since_hit            = game->play.clock_ms - entity->hit_on_clock_ms;
 | 
			
		||||
                Dqn_usize const HIT_CONFIRM_DURATION_MS = 8 * 16;
 | 
			
		||||
                if (ms_since_hit < HIT_CONFIRM_DURATION_MS) {
 | 
			
		||||
                    sprite_colour   = TELY_COLOUR_RED_V4;
 | 
			
		||||
                    sprite_colour.g = ((1.f / HIT_CONFIRM_DURATION) * frames_elapsed_since_hit);
 | 
			
		||||
                    sprite_colour.b = ((1.f / HIT_CONFIRM_DURATION) * frames_elapsed_since_hit);
 | 
			
		||||
                    sprite_colour.g = ((1.f / HIT_CONFIRM_DURATION_MS) * ms_since_hit);
 | 
			
		||||
                    sprite_colour.b = ((1.f / HIT_CONFIRM_DURATION_MS) * ms_since_hit);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -2483,7 +2485,6 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
 | 
			
		||||
                Dqn_V2 label_p = Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0, -0.25f));
 | 
			
		||||
                TELY_Render_TextF(renderer, label_p, Dqn_V2_InitNx2(0.f, 0.1f), "CONVERTED");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        DQN_FOR_UINDEX(anim_index, entity->extra_cosmetic_anims.size) {
 | 
			
		||||
 | 
			
		||||
@ -191,11 +191,12 @@ struct FP_GameEntity
 | 
			
		||||
    // NOTE: The entity hit box is positioned at the center of the entity.
 | 
			
		||||
    Dqn_V2                                local_hit_box_size;
 | 
			
		||||
    Dqn_V2                                local_hit_box_offset;
 | 
			
		||||
    Dqn_f32                               trauma01;
 | 
			
		||||
 | 
			
		||||
    Dqn_V2                                attack_box_size;
 | 
			
		||||
    Dqn_V2                                attack_box_offset;
 | 
			
		||||
    bool                                  attack_processed;
 | 
			
		||||
    Dqn_usize                             hit_on_frame;
 | 
			
		||||
    Dqn_usize                             hit_on_clock_ms;
 | 
			
		||||
    bool                                  is_dying;
 | 
			
		||||
    uint64_t                              last_attack_timestamp;
 | 
			
		||||
    uint64_t                              attack_cooldown_ms;
 | 
			
		||||
@ -261,8 +262,6 @@ struct FP_GameCamera
 | 
			
		||||
    Dqn_V2  world_pos_target;
 | 
			
		||||
    Dqn_f32 rotate_rads;
 | 
			
		||||
    Dqn_V2  scale;
 | 
			
		||||
    Dqn_f32 shake_intensity;
 | 
			
		||||
    Dqn_f64 shake_duration;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum FP_GameAudio
 | 
			
		||||
@ -332,6 +331,7 @@ struct FP_GamePlay
 | 
			
		||||
    FP_GameEntityHandle                   prev_hot_entity;
 | 
			
		||||
    FP_GameEntityHandle                   prev_active_entity;
 | 
			
		||||
 | 
			
		||||
    FP_GameEntityHandle                   camera_tracking_entity;
 | 
			
		||||
    FP_GameCamera                         camera;
 | 
			
		||||
    Dqn_f32                               meters_to_pixels;
 | 
			
		||||
    uint64_t                              clock_ms;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user