camera shake
This commit is contained in:
parent
25592d24d3
commit
4c194d3b39
12
src/entity.h
12
src/entity.h
@ -34,6 +34,8 @@ enum entity_prop {
|
||||
ENTITY_PROP_BULLET,
|
||||
ENTITY_PROP_TRACER,
|
||||
|
||||
ENTITY_PROP_QUAKE,
|
||||
|
||||
ENTITY_PROP_ATTACHED,
|
||||
|
||||
/* Test props */
|
||||
@ -246,6 +248,14 @@ struct entity {
|
||||
struct v2 tracer_gradient_start;
|
||||
struct v2 tracer_gradient_end;
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Quake */
|
||||
|
||||
/* ENTITY_PROP_QUAKE */
|
||||
|
||||
f32 quake_intensity;
|
||||
f32 quake_fade; /* How much intensity to lose per second */
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Testing */
|
||||
|
||||
@ -269,6 +279,8 @@ struct entity {
|
||||
u32 camera_lerp_continuity_gen;
|
||||
struct xform camera_xform_target; /* Calculated from camera_follow */
|
||||
u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */
|
||||
|
||||
f32 shake;
|
||||
};
|
||||
|
||||
struct entity_array {
|
||||
|
||||
50
src/game.c
50
src/game.c
@ -222,7 +222,7 @@ INTERNAL void spawn_test_entities(void)
|
||||
}
|
||||
|
||||
/* Enemy */
|
||||
#if 0
|
||||
#if 1
|
||||
{
|
||||
struct entity *e = entity_alloc(root);
|
||||
|
||||
@ -1144,23 +1144,33 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
tracer->tracer_gradient_end = pos;
|
||||
tracer->tracer_gradient_start = v2_sub(pos, v2_mul(ent->linear_velocity, tracer->tracer_fade_duration));
|
||||
}
|
||||
|
||||
/* Spawn quake */
|
||||
{
|
||||
struct entity *quake = entity_alloc(root);
|
||||
entity_set_xform(quake, XFORM_POS(pos));
|
||||
quake->quake_intensity = 0.02f;
|
||||
quake->quake_fade = quake->quake_intensity / 0.01f;
|
||||
entity_enable_prop(quake, ENTITY_PROP_QUAKE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update camera position
|
||||
* Update cameras
|
||||
* ========================== */
|
||||
|
||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||
struct entity *ent = &store->entities[entity_index];
|
||||
if (!entity_is_valid_and_active(ent)) continue;
|
||||
|
||||
/* Camera follow */
|
||||
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
||||
struct entity *follow = entity_from_handle(store, ent->camera_follow);
|
||||
if (!entity_has_prop(ent, ENTITY_PROP_CAMERA)) continue;
|
||||
|
||||
struct xform xf = entity_get_xform(ent);
|
||||
|
||||
/* Camera follow */
|
||||
{
|
||||
struct entity *follow = entity_from_handle(store, ent->camera_follow);
|
||||
|
||||
f32 aspect_ratio = 1.0;
|
||||
{
|
||||
struct xform quad_xf = xform_mul(entity_get_xform(ent), ent->camera_quad_xform);
|
||||
@ -1185,8 +1195,36 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
xf = ent->camera_xform_target;
|
||||
}
|
||||
ent->camera_applied_lerp_continuity_gen_plus_one = ent->camera_lerp_continuity_gen + 1;
|
||||
}
|
||||
|
||||
/* Camera shake */
|
||||
{
|
||||
/* TODO: Update based on distance to quake */
|
||||
ent->shake = 0;
|
||||
for (u64 quake_ent_index = 0; quake_ent_index < store->reserved; ++quake_ent_index) {
|
||||
struct entity *quake = &store->entities[quake_ent_index];
|
||||
if (!entity_is_valid_and_active(quake)) continue;
|
||||
if (!entity_has_prop(quake, ENTITY_PROP_QUAKE)) continue;
|
||||
ent->shake += quake->quake_intensity;
|
||||
}
|
||||
}
|
||||
|
||||
entity_set_xform(ent, xf);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update quakes
|
||||
* ========================== */
|
||||
|
||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||
struct entity *ent = &store->entities[entity_index];
|
||||
if (!entity_is_valid_and_active(ent)) continue;
|
||||
if (!entity_has_prop(ent, ENTITY_PROP_QUAKE)) continue;
|
||||
|
||||
ent->quake_intensity = max_f32(0, ent->quake_intensity - (ent->quake_fade * dt));
|
||||
if (ent->quake_intensity <= 0) {
|
||||
entity_enable_prop(ent, ENTITY_PROP_RELEASE_NEXT_TICK);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
|
||||
47
src/user.c
47
src/user.c
@ -388,10 +388,6 @@ INTERNAL void pubilsh_game_cmds(struct game_cmd_list *list)
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update
|
||||
* ========================== */
|
||||
|
||||
/* TODO: remove this (testing) */
|
||||
INTERNAL void debug_draw_xform(struct xform xf, u32 color_x, u32 color_y)
|
||||
{
|
||||
@ -432,24 +428,9 @@ INTERNAL void debug_draw_movement(struct entity *ent)
|
||||
draw_solid_arrow_ray(G.viewport_canvas, pos, vel_ray, thickness, arrow_len, color_vel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ========================== *
|
||||
* Update
|
||||
* ========================== */
|
||||
|
||||
INTERNAL void user_update(void)
|
||||
{
|
||||
@ -541,6 +522,7 @@ INTERNAL void user_update(void)
|
||||
|
||||
e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend);
|
||||
e->camera_xform_target = xform_lerp(e0->camera_xform_target, e1->camera_xform_target, tick_blend);
|
||||
e->shake = math_lerp(e0->shake, e1->shake, tick_blend);
|
||||
|
||||
e->tracer_gradient_start = v2_lerp(e0->tracer_gradient_start, e1->tracer_gradient_start, tick_blend);
|
||||
e->tracer_gradient_end = v2_lerp(e0->tracer_gradient_end, e1->tracer_gradient_end, tick_blend);
|
||||
@ -693,9 +675,24 @@ INTERNAL void user_update(void)
|
||||
G.debug_camera = !G.debug_camera;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Apply shake
|
||||
* ========================== */
|
||||
|
||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||
struct entity *ent = &store->entities[entity_index];
|
||||
if (!entity_is_valid_and_active(ent)) continue;
|
||||
if (ent->shake <= 0) continue;
|
||||
|
||||
f32 shake = ent->shake;
|
||||
|
||||
struct xform xf = entity_get_xform(ent);
|
||||
xf.og = v2_add(xf.og, v2_mul(v2_from_angle(sys_rand_f32(0, TAU)), shake));
|
||||
entity_set_xform(ent, xf);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update viewport
|
||||
* Update viewport from camera
|
||||
* ========================== */
|
||||
|
||||
/* Calculate screen viewport dimensions */
|
||||
@ -734,7 +731,7 @@ INTERNAL void user_update(void)
|
||||
G.viewport_cursor = v2_sub(G.screen_cursor, G.viewport_screen_offset);
|
||||
|
||||
/* ========================== *
|
||||
* Update view
|
||||
* Update view from camera
|
||||
* ========================== */
|
||||
|
||||
if (G.debug_camera) {
|
||||
@ -798,7 +795,7 @@ INTERNAL void user_update(void)
|
||||
G.world_cursor = xform_invert_mul_v2(G.world_view, G.viewport_cursor);
|
||||
|
||||
/* ========================== *
|
||||
* Update listener
|
||||
* Update listener from view
|
||||
* ========================== */
|
||||
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user