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_BULLET,
|
||||||
ENTITY_PROP_TRACER,
|
ENTITY_PROP_TRACER,
|
||||||
|
|
||||||
|
ENTITY_PROP_QUAKE,
|
||||||
|
|
||||||
ENTITY_PROP_ATTACHED,
|
ENTITY_PROP_ATTACHED,
|
||||||
|
|
||||||
/* Test props */
|
/* Test props */
|
||||||
@ -246,6 +248,14 @@ struct entity {
|
|||||||
struct v2 tracer_gradient_start;
|
struct v2 tracer_gradient_start;
|
||||||
struct v2 tracer_gradient_end;
|
struct v2 tracer_gradient_end;
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
/* Quake */
|
||||||
|
|
||||||
|
/* ENTITY_PROP_QUAKE */
|
||||||
|
|
||||||
|
f32 quake_intensity;
|
||||||
|
f32 quake_fade; /* How much intensity to lose per second */
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Testing */
|
/* Testing */
|
||||||
|
|
||||||
@ -269,6 +279,8 @@ struct entity {
|
|||||||
u32 camera_lerp_continuity_gen;
|
u32 camera_lerp_continuity_gen;
|
||||||
struct xform camera_xform_target; /* Calculated from camera_follow */
|
struct xform camera_xform_target; /* Calculated from camera_follow */
|
||||||
u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */
|
u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */
|
||||||
|
|
||||||
|
f32 shake;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_array {
|
struct entity_array {
|
||||||
|
|||||||
50
src/game.c
50
src/game.c
@ -222,7 +222,7 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Enemy */
|
/* Enemy */
|
||||||
#if 0
|
#if 1
|
||||||
{
|
{
|
||||||
struct entity *e = entity_alloc(root);
|
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_end = pos;
|
||||||
tracer->tracer_gradient_start = v2_sub(pos, v2_mul(ent->linear_velocity, tracer->tracer_fade_duration));
|
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) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!entity_is_valid_and_active(ent)) continue;
|
||||||
|
if (!entity_has_prop(ent, ENTITY_PROP_CAMERA)) continue;
|
||||||
|
|
||||||
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
|
||||||
/* Camera follow */
|
/* Camera follow */
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
{
|
||||||
struct entity *follow = entity_from_handle(store, ent->camera_follow);
|
struct entity *follow = entity_from_handle(store, ent->camera_follow);
|
||||||
|
|
||||||
struct xform xf = entity_get_xform(ent);
|
|
||||||
|
|
||||||
f32 aspect_ratio = 1.0;
|
f32 aspect_ratio = 1.0;
|
||||||
{
|
{
|
||||||
struct xform quad_xf = xform_mul(entity_get_xform(ent), ent->camera_quad_xform);
|
struct xform quad_xf = xform_mul(entity_get_xform(ent), ent->camera_quad_xform);
|
||||||
@ -1185,7 +1195,35 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
xf = ent->camera_xform_target;
|
xf = ent->camera_xform_target;
|
||||||
}
|
}
|
||||||
ent->camera_applied_lerp_continuity_gen_plus_one = ent->camera_lerp_continuity_gen + 1;
|
ent->camera_applied_lerp_continuity_gen_plus_one = ent->camera_lerp_continuity_gen + 1;
|
||||||
entity_set_xform(ent, xf);
|
}
|
||||||
|
|
||||||
|
/* 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);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Update
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
/* TODO: remove this (testing) */
|
/* TODO: remove this (testing) */
|
||||||
INTERNAL void debug_draw_xform(struct xform xf, u32 color_x, u32 color_y)
|
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);
|
draw_solid_arrow_ray(G.viewport_canvas, pos, vel_ray, thickness, arrow_len, color_vel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Update
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INTERNAL void user_update(void)
|
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_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->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_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);
|
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;
|
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 */
|
/* 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);
|
G.viewport_cursor = v2_sub(G.screen_cursor, G.viewport_screen_offset);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update view
|
* Update view from camera
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (G.debug_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);
|
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