2 Commits

Author SHA1 Message Date
Jojangles 4158674031 fp: Add camera shake 2023-10-18 10:28:15 +11:00
doylet 1de986b6ac fp: Add a hit confirmation visual marker 2023-10-18 00:19:09 +11:00
2 changed files with 44 additions and 3 deletions
+41 -3
View File
@@ -1996,6 +1996,24 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
if (entity->flags & FP_GameEntityFlag_CameraTracking) { if (entity->flags & FP_GameEntityFlag_CameraTracking) {
FP_GameCamera *camera = &game->play.camera; 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; camera->world_pos_target = FP_Game_CalcEntityWorldPos(game, entity->handle) * camera->scale;
} }
@@ -2244,13 +2262,20 @@ void FP_Update(TELY_Platform *platform, FP_Game *game, TELY_PlatformInput *input
continue; continue;
} }
defender->hp = defender->hp >= attacker->base_attack ? defender->hp - attacker->base_attack : 0; 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;
}
if (defender->hp <= 0) { if (defender->hp <= 0) {
if (!defender->is_dying) { if (!defender->is_dying) {
FP_GameEntity *coin_receiver = FP_Game_GetEntity(game, attacker->projectile_owner); FP_GameEntity *coin_receiver = FP_Game_GetEntity(game, attacker->projectile_owner);
if (FP_Game_IsNilEntity(coin_receiver)) if (FP_Game_IsNilEntity(coin_receiver))
coin_receiver = attacker; coin_receiver = attacker;
coin_receiver->coins += 1; coin_receiver->coins += 2;
} }
defender->is_dying = true; defender->is_dying = true;
} }
@@ -2433,13 +2458,26 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
if (sprite.flip & TELY_AssetFlip_Y) if (sprite.flip & TELY_AssetFlip_Y)
dest_rect.size.h *= -1.f; // NOTE: Flip the texture vertically 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) {
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.a *= entity->action.sprite_alpha;
TELY_Render_TextureColourV4(renderer, TELY_Render_TextureColourV4(renderer,
sprite.sheet->tex_handle, sprite.sheet->tex_handle,
src_rect, src_rect,
dest_rect, dest_rect,
Dqn_V2_Zero /*rotate origin*/, Dqn_V2_Zero /*rotate origin*/,
0.f /*rotate radians*/, 0.f /*rotate radians*/,
TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, entity->action.sprite_alpha)); sprite_colour);
if (entity->converted_faction) { if (entity->converted_faction) {
Dqn_V2 label_p = Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0, -0.25f)); Dqn_V2 label_p = Dqn_Rect_InterpolatedPoint(dest_rect, Dqn_V2_InitNx2(0, -0.25f));
+3
View File
@@ -195,6 +195,7 @@ struct FP_GameEntity
Dqn_V2 attack_box_size; Dqn_V2 attack_box_size;
Dqn_V2 attack_box_offset; Dqn_V2 attack_box_offset;
bool attack_processed; bool attack_processed;
Dqn_usize hit_on_frame;
bool is_dying; bool is_dying;
uint64_t last_attack_timestamp; uint64_t last_attack_timestamp;
uint64_t attack_cooldown_ms; uint64_t attack_cooldown_ms;
@@ -260,6 +261,8 @@ struct FP_GameCamera
Dqn_V2 world_pos_target; Dqn_V2 world_pos_target;
Dqn_f32 rotate_rads; Dqn_f32 rotate_rads;
Dqn_V2 scale; Dqn_V2 scale;
Dqn_f32 shake_intensity;
Dqn_f64 shake_duration;
}; };
enum FP_GameAudio enum FP_GameAudio