death screen structure and animation

This commit is contained in:
Lephenixnoir 2023-06-15 20:22:33 +02:00
parent 81f3f9f9a5
commit 3daf3240be
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
9 changed files with 89 additions and 20 deletions

View File

@ -31,6 +31,8 @@ set(ASSETS
assets-cg/lepheyatis_logo.png
assets-cg/font_boson.png
assets-cg/font_energy.png
assets-cg/font_energy2.png
assets-cg/font_energy3.png
assets-cg/erik_running.gif
assets-cg/erik_jumping.gif
assets-cg/stages/stage1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

BIN
assets-cg/font_energy2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

BIN
assets-cg/font_energy3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

View File

@ -33,9 +33,9 @@ font_boson.png:
proportional: true
height: 9
font_energy.png:
font_energy*.png:
type: bopti-image
name: img_font_energy
name_regex: (.*)\.png img_\1
profile: p8_rgb565a
*.gif:

View File

@ -9,14 +9,17 @@ struct level level_create(int level)
switch(level) {
default:
l.name = "geon";
l.gen = std::make_unique<struct gen1>();
l.bgcolor = RGB24(0x49759f);
break;
case 2:
l.name = "acceleron";
l.gen = std::make_unique<AcceleronGenerator>();
l.bgcolor = RGB24(0xe7c272);
break;
case 3:
l.name = "radion";
l.gen = std::make_unique<struct gen3>();
l.bgcolor = C_WHITE;
break;

View File

@ -32,6 +32,7 @@ struct platform {
struct Generator;
struct level {
char const *name;
std::vector<struct platform> platform_buffer;
std::unique_ptr<Generator> gen;
uint16_t bgcolor;

View File

@ -311,7 +311,7 @@ int play_level(int level_id)
}
}
if(game.t_death >= TIME_DEATH_ANIMATION)
if(game.t_death >= TIME_DEATH_ANIMATION && keybuffer.shift)
break;
game_advance(&game);

View File

@ -169,35 +169,47 @@ void render_anim_frame(int x, int y, struct anim *anim, int frame)
anim->frames[frame]);
}
static bool render_energy_str_glyph_params(int c, int *ix, int *w)
static bool render_energy_str_glyph_params(int size, int c, int *ix, int *w)
{
size = (size >= 1 && size <= 3) ? size-1 : 0;
int dw[3] = { 11, 14, 18 };
int ow[3] = { 8, 11, 16 };
int dotx[3] = { 127, 157, 198 };
int dotw[3] = { 4, 5, 7 };
int perx[3] = { 132, 164, 207 };
int perw[3] = { 8, 13, 16 };
if(c >= '0' && c <= '9') {
*ix = 13 * (c - '0') - (c >= '2' ? 3 : 0);
*w = (c == '1') ? 8 : 11;
*ix = (dw[size] + 2) * (c-'0') - (c >= '2' ? (dw[size]-ow[size]) : 0);
*w = (c == '1') ? ow[size] : dw[size];
return true;
}
if(c == '.') {
*ix = 127;
*w = 4;
*ix = dotx[size];
*w = dotw[size];
return true;
}
if(c == '%') {
*ix = 132;
*w = 8;
*ix = perx[size];
*w = perw[size];
return true;
}
return false;
}
void render_energy_str(int x, int y, int halign, char const *str)
void render_energy_str(int x, int y, int halign, int size, char const *str)
{
extern image_t img_font_energy;
extern image_t img_font_energy, img_font_energy2, img_font_energy3;
image_t const *img =
(size == 3) ? &img_font_energy3 :
(size == 2) ? &img_font_energy2 :
&img_font_energy;
int ix, w;
/* First compute width of string */
int total_width = 0;
for(int i = 0; str[i]; i++) {
if(render_energy_str_glyph_params(str[i], &ix, &w))
if(render_energy_str_glyph_params(size, str[i], &ix, &w))
total_width += w + 2;
}
total_width -= (total_width ? 2 : 0);
@ -210,10 +222,9 @@ void render_energy_str(int x, int y, int halign, char const *str)
/* Render string */
for(int i = 0; str[i]; i++) {
if(!render_energy_str_glyph_params(str[i], &ix, &w))
if(!render_energy_str_glyph_params(size, str[i], &ix, &w))
continue;
azrp_subimage(x, y, &img_font_energy, ix, 0, w,
img_font_energy.height, DIMAGE_NONE);
azrp_subimage(x, y, img, ix, 0, w, img->height, DIMAGE_NONE);
x += w + 2;
}
}
@ -324,6 +335,16 @@ static void render_game_platforms(struct game &game)
/* Blue platform particle effect's buffer image */
static image_t *_effect_bpp = NULL;
static int cubic(int start, int end, num t, num tmax)
{
if(t >= tmax)
return end;
t = t / tmax;
num x = num(1.0) - (num(1.0) - t) * (num(1.0) - t) * (num(1.0) - t);
return (int)(num(start) + num(end - start) * x + num(0.5));
}
void render_game(struct game &game, prof_t *perf_comp)
{
azrp_perf_clear();
@ -335,6 +356,9 @@ void render_game(struct game &game, prof_t *perf_comp)
bool alive = (player->stance != player::Collided);
struct platform *standing_on = game_platform_under_player(&game, player);
char energy_str[32];
sprintf(energy_str, "%.2f%%", (float)player->energy_percent);
/* Standard gameplay before collision */
if(alive) {
prof_enter_norec(*perf_comp);
@ -357,10 +381,8 @@ void render_game(struct game &game, prof_t *perf_comp)
}
/* Render energy score */
char energy_str[32];
sprintf(energy_str, "%.2f%%", (float)player->energy_percent);
azrp_rect(DWIDTH-100, 4, 96, 20, AZRP_RECT_DARKEN);
render_energy_str(DWIDTH-8, 8, DTEXT_RIGHT, energy_str);
render_energy_str(DWIDTH-8, 8, DTEXT_RIGHT, 1, energy_str);
}
/* End transition and end screen */
else {
@ -384,13 +406,54 @@ void render_game(struct game &game, prof_t *perf_comp)
}
/* End screen elements appearing in order */
num t_endscreen = game.t_death - TIME_DEATH_ANIMATION - num(0.5);
num t_endscreen = game.t_death - num(1.0);
int xe = 40, ye0 = 20, ye = ye0;
if(t_endscreen >= num(0.0)) {
azrp_print(xe, ye, C_WHITE, "experiments %s", game.level.name);
}
if(t_endscreen >= num(0.1)) {
ye += 15;
azrp_text(xe, ye, C_WHITE, "UNDISCOVERED");
}
if(t_endscreen >= num(0.2)) {
ye += 20;
azrp_text(xe, ye+2, C_WHITE, "energy");
azrp_text(xe, ye+11, C_WHITE, "reading");
render_energy_str(xe+65, ye, DTEXT_LEFT, 3, energy_str);
azrp_text(xe+65, ye+22, RGB24(0x9cefe3), "new peak");
}
if(t_endscreen >= num(0.3)) {
ye += 40;
azrp_text(xe, ye+1, C_WHITE, "old peak");
// TODO: Old energy str
render_energy_str(xe+65, ye, DTEXT_LEFT, 1, "0.00%");
}
if(t_endscreen >= num(0.4)) {
ye += 20;
azrp_text(xe, ye, C_WHITE, "100%");
azrp_rect(xe, ye+10, 160, 40, AZRP_RECT_WHITEN);
azrp_text(xe, ye+49, C_WHITE, "0%");
int h_footer = 30;
int y_footer = cubic(DHEIGHT, DHEIGHT - h_footer,
t_endscreen - num(0.4), num(0.2));
azrp_rect(0, y_footer, DWIDTH, h_footer, C_WHITE);
azrp_text_opt(8, y_footer + 14, NULL, RGB24(0x49759f),
DTEXT_LEFT, DTEXT_MIDDLE, "exit: back", -1);
azrp_text_opt(DWIDTH-8, y_footer + 14, NULL, RGB24(0x49759f),
DTEXT_RIGHT, DTEXT_MIDDLE, "SHIFT: AGAIN",-1);
}
if(t_endscreen >= num(0.5)) {
xe = 230;
ye = ye0;
// TODO: Run count
azrp_text(xe, ye, C_WHITE, "run count 42");
azrp_text(xe, ye+10, C_WHITE, "particle trace");
}
if(t_endscreen >= num(0.6)) {
ye += 30;
// TODO: Crazy particle trace animation
}
}