screenshake during major attacks
This commit is contained in:
parent
45b13d898c
commit
b04333ddda
|
@ -191,6 +191,10 @@ static bool attack_apply(game_t *game, aoe_t *aoe, entity_t *target)
|
|||
(target_f->enemy_data == NULL) ? C_RED : C_WHITE);
|
||||
game_add_entity(game, particle);
|
||||
|
||||
/* Quick screenshake for entities hit by a bullet */
|
||||
if(aoe->type == AOE_BULLET)
|
||||
game_shake(game, 3, fix(0.1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
10
src/game.c
10
src/game.c
|
@ -9,6 +9,7 @@
|
|||
#include "comp/particle.h"
|
||||
#include "aoe.h"
|
||||
|
||||
#include <gint/defs/util.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
bool game_load(game_t *g, level_t const *level)
|
||||
|
@ -87,6 +88,15 @@ void game_next_wave(game_t *g)
|
|||
g->wave_left[i] = wave->entries[i].amount;
|
||||
}
|
||||
|
||||
void game_shake(game_t *g, int amplitude, fixed_t duration)
|
||||
{
|
||||
if(g->screenshake_amplitude > amplitude)
|
||||
return;
|
||||
|
||||
g->screenshake_duration = max(g->screenshake_duration, duration);
|
||||
g->screenshake_amplitude = amplitude;
|
||||
}
|
||||
|
||||
//---
|
||||
// Object management functions
|
||||
//---
|
||||
|
|
|
@ -23,6 +23,9 @@ typedef struct game {
|
|||
/* Time when victory was reached or defeat was dealt */
|
||||
fixed_t time_victory;
|
||||
fixed_t time_defeat;
|
||||
/* Screenshake duration left (effect disabled when 0), and amplitude */
|
||||
fixed_t screenshake_duration;
|
||||
int screenshake_amplitude;
|
||||
/* List of entities */
|
||||
entity_t **entities;
|
||||
int entity_count;
|
||||
|
@ -59,6 +62,9 @@ bool game_current_wave_finished(game_t const *g);
|
|||
/* Move to next wave */
|
||||
void game_next_wave(game_t *g);
|
||||
|
||||
/* Shake the screen for the specified amount of time */
|
||||
void game_shake(game_t *g, int amplitude, fixed_t duration);
|
||||
|
||||
//---
|
||||
// Managing dynamic game elements
|
||||
//---
|
||||
|
|
12
src/main.c
12
src/main.c
|
@ -24,6 +24,7 @@
|
|||
#include <gint/timer.h>
|
||||
#include <gint/kmalloc.h>
|
||||
#include <gint/drivers/r61524.h>
|
||||
#include <gint/defs/util.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -568,6 +569,8 @@ int main(void)
|
|||
visible_set_anim(player, &anims_player_Attack, 2);
|
||||
player_f->current_attack = aoe;
|
||||
player_f->attack_follows_movement = true;
|
||||
|
||||
game_shake(&game, 9, fix(0.7));
|
||||
}
|
||||
if(can_attack && keydown(KEY_F3)) {
|
||||
entity_t *aoe = aoe_make_attack( AOE_JUDGEMENT, player,
|
||||
|
@ -577,6 +580,8 @@ int main(void)
|
|||
visible_set_anim(player, &anims_player_Attack, 2);
|
||||
player_f->current_attack = aoe;
|
||||
player_f->attack_follows_movement = false;
|
||||
|
||||
game_shake(&game, 5, fix(1.3));
|
||||
}
|
||||
if(can_attack && keydown(KEY_F4)) {
|
||||
entity_t *aoe = aoe_make_attack(AOE_BULLET, player,
|
||||
|
@ -619,6 +624,13 @@ int main(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Reduce screenshake time */
|
||||
game.screenshake_duration -= dt;
|
||||
if(game.screenshake_duration < 0) {
|
||||
game.screenshake_duration = 0;
|
||||
game.screenshake_amplitude = 0;
|
||||
}
|
||||
|
||||
game.time_total += dt;
|
||||
game.time_wave += dt;
|
||||
|
||||
|
|
29
src/render.c
29
src/render.c
|
@ -120,7 +120,8 @@ fixed_t camera_ppu(camera_t const *c)
|
|||
// Rendering
|
||||
//---
|
||||
|
||||
static void render_map_layer(map_t const *m, camera_t const *c, int layer)
|
||||
static void render_map_layer(map_t const *m, camera_t const *c, int ss_x,
|
||||
int ss_y, int layer)
|
||||
{
|
||||
/* Render floor and walls */
|
||||
for(int row = -2; row < m->height + 2; row++)
|
||||
|
@ -128,6 +129,8 @@ static void render_map_layer(map_t const *m, camera_t const *c, int layer)
|
|||
tile_t *t = map_tile(m, col, row);
|
||||
vec2 tile_pos = { fix(col), fix(row) };
|
||||
ivec2 p = camera_map2screen(c, tile_pos);
|
||||
p.x += ss_x;
|
||||
p.y += ss_y;
|
||||
|
||||
if(!t && layer == CEILING) {
|
||||
drect(p.x, p.y, p.x+15, p.y+15, C_BLACK);
|
||||
|
@ -208,7 +211,7 @@ static void render_shadow(int cx, int cy, int shadow_size)
|
|||
}
|
||||
|
||||
static void render_entities(game_t const *g, camera_t const *camera,
|
||||
entity_measure_t *measure, bool show_hitboxes)
|
||||
entity_measure_t *measure, int ss_x, int ss_y, bool show_hitboxes)
|
||||
{
|
||||
uint16_t *rendering_order;
|
||||
int count = game_sort_entities(g, measure, &rendering_order);
|
||||
|
@ -231,6 +234,8 @@ static void render_entities(game_t const *g, camera_t const *camera,
|
|||
}
|
||||
|
||||
ivec2 scr = camera_map2screen(camera, xy);
|
||||
scr.x += ss_x;
|
||||
scr.y += ss_y;
|
||||
int elevated_y = scr.y - fround(16 * z);
|
||||
|
||||
/* Show shadow */
|
||||
|
@ -346,18 +351,26 @@ void render_game(game_t const *g, bool show_hitboxes)
|
|||
{
|
||||
camera_t const *camera = &g->camera;
|
||||
|
||||
/* Screenshake displacement */
|
||||
int ss_x=0, ss_y=0;
|
||||
if(g->screenshake_duration > 0) {
|
||||
int amp = g->screenshake_amplitude;
|
||||
ss_x = rand() % amp - (amp/2);
|
||||
ss_y = rand() % amp - (amp/2);
|
||||
}
|
||||
|
||||
/* Render map floor and floor entities */
|
||||
render_map_layer(g->map, camera, HORIZONTAL);
|
||||
render_entities(g, camera, floor_depth_measure, show_hitboxes);
|
||||
render_map_layer(g->map, camera, ss_x, ss_y, HORIZONTAL);
|
||||
render_entities(g, camera, floor_depth_measure, ss_x, ss_y, show_hitboxes);
|
||||
|
||||
/* Render map walls and vertical entities
|
||||
TODO ECS: Sort walls and wall entities together for proper ordering!*/
|
||||
render_map_layer(g->map, camera, VERTICAL);
|
||||
render_entities(g, camera, wall_depth_measure, show_hitboxes);
|
||||
render_map_layer(g->map, camera, ss_x, ss_y, VERTICAL);
|
||||
render_entities(g, camera, wall_depth_measure, ss_x, ss_y, show_hitboxes);
|
||||
|
||||
/* Render ceiling tiles (including out of bounds) and ceiling entities */
|
||||
render_map_layer(g->map, camera, CEILING);
|
||||
render_entities(g, camera, ceiling_depth_measure, show_hitboxes);
|
||||
render_map_layer(g->map, camera, ss_x, ss_y, CEILING);
|
||||
render_entities(g, camera, ceiling_depth_measure, ss_x,ss_y,show_hitboxes);
|
||||
|
||||
extern font_t font_rogue;
|
||||
font_t const *old_font = dfont(&font_rogue);
|
||||
|
|
Loading…
Reference in New Issue