debug and improve blue platform animation

This commit is contained in:
Lephenixnoir 2023-07-31 19:52:29 +02:00
parent 339c538d63
commit 23716a7637
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
4 changed files with 101 additions and 28 deletions

View File

@ -34,6 +34,8 @@ struct player
void get_anim(struct anim **anim, int *frame);
/* Current animation frame (fractional for variable animation speed). */
num frame;
/* Current blue platform animation state */
num blueanim;
/* Whether the player is airborne. */
bool airborne() const { return this->stance != Running; }

View File

@ -106,6 +106,7 @@ int play_level(int level_id)
player->vz = 3.0;
player->platform = 0;
player->stance = player::Falling;
player->blueanim = 0.0;
player->jump_dir = 0;
player->jump_t = 0.0;
player->height = 1.0;
@ -132,6 +133,13 @@ int play_level(int level_id)
camera->platform,
str(camera->angle_vector));
if(level_id == 4) {
player->energy_percent = 350.0;
player->height = num(-10.0);
game.t_death = num(10.0);
level_update(&game.level, num(350.0));
}
bool game_run = true;
while(game_run) {
while(!need_frame) sleep();
@ -305,6 +313,20 @@ int play_level(int level_id)
standing_on->falling = true;
}
/* Blue platform animation progress */
if(standing_on && standing_on->type == PLATFORM_BLUE) {
player->blueanim += dt;
if(player->blueanim >= num(2.0))
player->blueanim -= num(2.0);
}
else if(player->blueanim > 0) {
if(player->blueanim < num(2.0))
player->blueanim = num(2.0);
player->blueanim += dt;
if(player->blueanim >= num(2.5))
player->blueanim = 0;
}
for(auto &p: game.level.platform_buffer) {
if(p.type == PLATFORM_RED && p.falling) {
p.height -= PLATFORM_FALL_SPEED * dt;

View File

@ -5,6 +5,7 @@
#include "game.h"
#include "util.h"
#include <azur/gint/render.h>
#include <gint/kmalloc.h>
void camera::set_fov(num fov)
{
@ -119,7 +120,7 @@ static void gradient(uint32_t RGB1, uint32_t RGB2, uint16_t *gradient, int N)
void render_init(void)
{
/* Generate a gradient ramp for blue platforms */
gradient(0x5090d0, 0x2060b0, blue_ramp, 32);
gradient(0x56a3ef, 0x25c5ba, blue_ramp, 32);
}
uint16_t render_color_blue_platform(num t)
@ -169,6 +170,18 @@ void render_anim_frame(int x, int y, struct anim *anim, int frame)
anim->frames[frame]);
}
void render_anim_frame_palette(int x, int y, struct anim *anim, int frame,
uint16_t const *palette)
{
image_t img = *anim->frames[frame];
img.palette = (uint16_t *)palette;
azrp_image(
x + anim->x_offsets[frame] - anim->x_anchor,
y + anim->y_offsets[frame] - anim->y_anchor,
&img);
}
static bool render_energy_str_glyph_params(int size, int c, int *ix, int *w)
{
size = (size >= 1 && size <= 3) ? size-1 : 0;
@ -229,55 +242,66 @@ void render_energy_str(int x, int y, int halign, int size, char const *str)
}
}
void render_effect_bpp(image_t **image, num t)
static void render_effect_bpp_internal(image_t **image, num16 t)
{
enum { BPP_PARTICLE = 0x81 };
static uint16_t bpp_palette[] = {
[0] = RGB24(0xff00ff), /* alpha */
[BPP_PARTICLE-0x80] = RGB24(0x5090d0),
RGB24(0xff00ff), /* alpha */
C_WHITE,
};
static int const bpp_W = 34;
static int const bpp_W = 35;
static int const bpp_H = 68;
if(!*image) {
*image = image_alloc(bpp_W, bpp_H, IMAGE_P8_RGB565A);
if(!*image)
return;
image_set_palette(*image, bpp_palette, 2, false);
}
image_clear(*image);
uint8_t *pixels = (uint8_t *)(*image)->data;
for(int i = 0; i < 24; i++) {
/* Particule #i appears after i 32-th of a second */
num start = num(i) / 32;
for(int i = 0; i < 32; i++) {
/* Particule #i is visible from t=i/32 until t=i/32+1. Local time
variable is normalized to 0..1. */
num16 start = num16(i) / 32;
if(t < start)
continue;
num16 local_time = num16(2 * ((t - start) % num(0.5)));
// if(local_time < num16(0) || local_time >= num16(1))
// abort();
num16 local_time = (t - start) % num16(1);
int x0_int = (23 * i) % (bpp_W - 2);
int x0_int = (bpp_W / 2 - 17) + (((967 * i) >> 4) & 31);
/* 0+(...)&31 => [0,31] = [0,W-3] */
num16 x0 = num16(x0_int);
num16 y0 = num16(bpp_H - 3 - ((37 * i) & 15));
num16 y0 = num16(bpp_H - 4 - ((37 * i) & 15)); /* [H-19, H-4] */
num16 vx = num16(bpp_W / 2 - x0_int) / 4;
num16 vx = num16(bpp_W / 2 - x0_int) / 2;
num16 x = x0 + vx * local_time;
num16 y = y0 - (bpp_H - 18) * local_time;
num16 y = y0 - (bpp_H - 19) * local_time; /* (0, H-4] */
for(int dy = 0; dy <= 3; dy++)
for(int dx = 0; dx <= 3; dx++) {
int size = 4 - (y.ifloor() >> 4);
for(int dy = 0; dy <= size; dy++)
for(int dx = 0; dx <= size; dx++) {
// if((unsigned)((int)y + dy) >= bpp_H)
// abort();
// if((unsigned)((int)x + dx) >= bpp_W)
// abort();
pixels[((int)y + dy) * (*image)->stride + (int)x + dx] =
BPP_PARTICLE;
pixels[((int)y + dy) * (*image)->stride + (int)x + dx] = 0x81;
}
}
}
void render_effect_bpp(image_t **image, num global_t)
{
/* Time within the animation (loops every second). Two segments:
- t = [0..1) for the animation startup (particles appear progressively)
- t = [1..2) for the loop (all particles visible) */
num16 t = num16(global_t).frac() + num16(global_t >= 1);
return render_effect_bpp_internal(image, t);
}
void render_effect_dp(int x, int y, int count, num t, int color)
{
for(int i = 0; i < count; i++) {
@ -353,7 +377,6 @@ void render_game(struct game &game, prof_t *perf_comp)
struct player *player = &game.player;
vec3 player_dot = camera_project_point(&game.camera, player->pos());
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);
@ -373,17 +396,33 @@ void render_game(struct game &game, prof_t *perf_comp)
struct anim *player_anim;
int player_frame;
player->get_anim(&player_anim, &player_frame);
render_anim_frame((int)player_dot.x, (int)player_dot.y,
player_anim, player_frame);
if(standing_on && standing_on->type == PLATFORM_BLUE) {
/* Make a bluer palette palette when running on blue platforms */
uint16_t palette[16];
int blue_tint_alpha = 0;
if(player->blueanim > 0) {
num t = (player->blueanim >= 2)
? (num(2.5) - player->blueanim) / 2
: min(player->blueanim, num(0.25));
blue_tint_alpha = (t * 96).ifloor();
}
for(int i = 0; i < 16; i++) {
palette[i] = render_blend(
player_anim->frames[player_frame]->palette[i],
RGB24(0xb0d0f0), blue_tint_alpha);
}
render_anim_frame_palette((int)player_dot.x, (int)player_dot.y,
player_anim, player_frame, palette);
if(player->blueanim > 0) {
prof_enter(game.perf.effect_bpp);
render_effect_bpp(&_effect_bpp, game.t);
render_effect_bpp(&_effect_bpp, player->blueanim);
azrp_image((int)player_dot.x - _effect_bpp->width / 2,
(int)player_dot.y - _effect_bpp->height + 2,
_effect_bpp);
prof_leave(game.perf.effect_bpp);
}
}
/* Render energy score */
azrp_rect(DWIDTH-100, 4, 96, 20, AZRP_RECT_DARKEN);
@ -466,6 +505,16 @@ void render_game(struct game &game, prof_t *perf_comp)
// TODO: Level-specific particle trace animation color?
shader_ptrace(xe, ye, C_RGB(24, 24, 8), game.level.bgcolor,
game.player.energy_percent >= 100, t_endscreen - num(0.6));
/*
// Debugging overflows on BPP effect
static num16 t = 0;
render_effect_bpp_internal(&_effect_bpp, t);
t.v = (t.v + 1) & 511;
azrp_image(azrp_width / 2 - _effect_bpp->width / 2,
azrp_height / 2 - _effect_bpp->height + 2,
_effect_bpp);
*/
}
}

View File

@ -38,7 +38,7 @@ using namespace libnum;
/* Vertical FOV, in degrees */
#define RENDER_FOV 120.0
/* Height of camera above the player's feet, in world units */
#define RENDER_EYE_HEIGHT num(1.0)
#define RENDER_EYE_HEIGHT num(1.15)
/* Number of sections visible in advance */
#define RENDER_DISTANCE 8
/* Distance between the player and the camera */