beautifully-animated hud XP bar
This commit is contained in:
parent
e5e5c0bfed
commit
c58c976c24
|
@ -49,7 +49,7 @@ set(ASSETS
|
|||
assets-cg/hud_life.png
|
||||
assets-cg/hud_stars.png
|
||||
assets-cg/hud_window.png
|
||||
assets-cg/hud_xp.png
|
||||
assets-cg/hud_xp.ase
|
||||
assets-cg/skillicons.png
|
||||
assets-cg/font_hud.png
|
||||
# Player animations
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
hud*.png:
|
||||
profile: p4
|
||||
|
||||
hud_xp.ase:
|
||||
custom-type: aseprite-anim
|
||||
name: frames_hud_xp
|
||||
profile: p4
|
||||
center: 6, 8
|
||||
next: Idle=Idle, Shine=Idle, Explode=Idle
|
||||
|
||||
font_rogue.png:
|
||||
type: font
|
||||
name: font_rogue
|
||||
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 234 B |
Binary file not shown.
23
src/anim.c
23
src/anim.c
|
@ -1,5 +1,6 @@
|
|||
#include "anim.h"
|
||||
#include <gint/display.h>
|
||||
#include <gint/defs/util.h>
|
||||
|
||||
/* Definition of simple and direction animations. */
|
||||
|
||||
|
@ -69,6 +70,11 @@ ANIM4(player, Walking);
|
|||
ANIM4(player, Attack);
|
||||
ANIM4(player, Hit);
|
||||
|
||||
/* HUD */
|
||||
ANIM1(hud_xp_Idle);
|
||||
ANIM1(hud_xp_Shine);
|
||||
ANIM1(hud_xp_Explode);
|
||||
|
||||
/* Animation functions. */
|
||||
|
||||
fixed_t (anim_duration)(anim_t const *anim)
|
||||
|
@ -109,6 +115,23 @@ void anim_frame_render(int x, int y, anim_frame_t const *frame)
|
|||
frame->x, frame->y, frame->w, frame->h, DIMAGE_NONE);
|
||||
}
|
||||
|
||||
void anim_frame_subrender(int x, int y, anim_frame_t const *frame, int left,
|
||||
int top, int width, int height)
|
||||
{
|
||||
if(!frame) return;
|
||||
if(width < 0) width = frame->w;
|
||||
if(height < 0) height = frame->h;
|
||||
|
||||
/* Basic clipping */
|
||||
if(left < 0) width += left, left = 0;
|
||||
if(top < 0) height += top, top = 0;
|
||||
width = min(width, frame->w - left);
|
||||
height = min(height, frame->h - top);
|
||||
|
||||
dsubimage(x - frame->cx, y - frame->cy + top, frame->sheet,
|
||||
frame->x + left, frame->y + top, width, height, DIMAGE_NONE);
|
||||
}
|
||||
|
||||
void anim_state_update(anim_state_t *state, fixed_t dt)
|
||||
{
|
||||
if(!state->frame) return;
|
||||
|
|
11
src/anim.h
11
src/anim.h
|
@ -54,9 +54,13 @@ fixed_t anim_duration(anim_t const *anim);
|
|||
/* Check if a frame is in an animation. */
|
||||
bool anim_in(anim_frame_t const *frame, anim_t const *anim, int index);
|
||||
|
||||
/* Render a frame at the center position (x,y). */
|
||||
/* Render a frame at the center position (x,y), similar to dimage(). */
|
||||
void anim_frame_render(int x, int y, anim_frame_t const *frame);
|
||||
|
||||
/* Render a subimage of a frame, similar to dsubimage(). */
|
||||
void anim_frame_subrender(int x, int y, anim_frame_t const *frame, int left,
|
||||
int top, int width, int height);
|
||||
|
||||
/* Update an animation to next frame. */
|
||||
void anim_state_update(anim_state_t *state, fixed_t dt);
|
||||
|
||||
|
@ -97,3 +101,8 @@ extern anim_t anims_player_Idle;
|
|||
extern anim_t anims_player_Walking;
|
||||
extern anim_t anims_player_Attack;
|
||||
extern anim_t anims_player_Hit;
|
||||
|
||||
/* HUD */
|
||||
extern anim_t anims_hud_xp_Idle;
|
||||
extern anim_t anims_hud_xp_Shine;
|
||||
extern anim_t anims_hud_xp_Explode;
|
||||
|
|
16
src/game.c
16
src/game.c
|
@ -35,6 +35,9 @@ bool game_load(game_t *g, level_t const *level)
|
|||
g->wave_left = NULL;
|
||||
game_next_wave(g);
|
||||
|
||||
g->hud_xp_anim.frame = anims_hud_xp_Idle.start[0];
|
||||
g->hud_xp_anim.elapsed = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -179,7 +182,16 @@ void game_remove_dead_entities(game_t *g)
|
|||
|
||||
if(f && f->HP == 0 && f->enemy_data != NULL && anim_finished) {
|
||||
/* Give XP points to player */
|
||||
player_add_xp(g->player_data, f->enemy_data->xp);
|
||||
bool lvup = player_add_xp(g->player_data, f->enemy_data->xp);
|
||||
|
||||
if(lvup) {
|
||||
g->hud_xp_anim.frame = anims_hud_xp_Explode.start[0];
|
||||
g->hud_xp_anim.elapsed = 0;
|
||||
}
|
||||
else if(!anim_in(g->hud_xp_anim.frame, &anims_hud_xp_Explode, 0)) {
|
||||
g->hud_xp_anim.frame = anims_hud_xp_Shine.start[0];
|
||||
g->hud_xp_anim.elapsed = 0;
|
||||
}
|
||||
|
||||
entity_mark_to_delete(e);
|
||||
}
|
||||
|
@ -360,6 +372,8 @@ void game_update_animations(game_t *g, fixed_t dt)
|
|||
if(getcomp(e, visible))
|
||||
visible_update(e, dt);
|
||||
}
|
||||
|
||||
anim_state_update(&g->hud_xp_anim, dt);
|
||||
}
|
||||
|
||||
void game_update_aoes(game_t *g, fixed_t dt)
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "map.h"
|
||||
#include "render.h"
|
||||
#include "anim.h"
|
||||
#include "level.h"
|
||||
#include "map.h"
|
||||
#include "pathfinding.h"
|
||||
#include "player.h"
|
||||
#include "render.h"
|
||||
|
||||
#include "comp/entity.h"
|
||||
|
||||
|
@ -47,6 +48,9 @@ typedef struct game {
|
|||
/* Enemies left to spawn; has level->waves[wave]->entry_count elements */
|
||||
uint8_t *wave_left;
|
||||
|
||||
/* XP bar animation */
|
||||
anim_state_t hud_xp_anim;
|
||||
|
||||
} game_t;
|
||||
|
||||
/* Allocate resources to load a level. */
|
||||
|
|
20
src/render.c
20
src/render.c
|
@ -400,13 +400,19 @@ void render_game(game_t const *g, bool show_hitboxes)
|
|||
0, img_hud_life.height - fill_height, img_hud_life.width, fill_height,
|
||||
DIMAGE_NONE);
|
||||
|
||||
/* Render XP bar */
|
||||
extern bopti_image_t img_hud_xp;
|
||||
fill_height = (img_hud_xp.height * g->player_data->xp_current) /
|
||||
max(g->player_data->xp_to_next_level, 1);
|
||||
dsubimage(343, DHEIGHT - 10 - fill_height, &img_hud_xp,
|
||||
0, img_hud_xp.height - fill_height, img_hud_xp.width, fill_height,
|
||||
DIMAGE_NONE);
|
||||
/* Render XP bar. The following values indicate the geometry of the XP bar
|
||||
so that we can show a partially-filled version of it */
|
||||
if(anim_in(g->hud_xp_anim.frame, &anims_hud_xp_Explode, 0)) {
|
||||
anim_frame_render(343, DHEIGHT-32, g->hud_xp_anim.frame);
|
||||
}
|
||||
else {
|
||||
static int const XP_FULL=22;
|
||||
int xp_current = g->player_data->xp_current;
|
||||
int xp_total = max(g->player_data->xp_to_next_level, 1);
|
||||
int fill_height = XP_FULL * xp_current / xp_total;
|
||||
anim_frame_subrender(343, DHEIGHT-32, g->hud_xp_anim.frame,
|
||||
0, XP_FULL - fill_height, -1, fill_height);
|
||||
}
|
||||
|
||||
/* Render skill icons */
|
||||
extern bopti_image_t img_skillicons;
|
||||
|
|
Loading…
Reference in New Issue