rogue font and bidirectional enemy animations

This commit is contained in:
Lephenixnoir 2021-07-16 11:06:28 +02:00
parent 48015da5cd
commit 4f5c24c13e
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
35 changed files with 88 additions and 27 deletions

View File

@ -51,14 +51,19 @@ set(ASSETS
assets-cg/skills/swing_left.png
assets-cg/skills/hit.png
# Enemies: Slime
assets-cg/enemies/slime_idle_down.png
assets-cg/enemies/slime_death.png
assets-cg/enemies/slime_idle_left.png
assets-cg/enemies/slime_idle_right.png
assets-cg/enemies/slime_death_left.png
assets-cg/enemies/slime_death_right.png
# Enemies: Bat
assets-cg/enemies/bat_idle_down.png
assets-cg/enemies/bat_death.png
assets-cg/enemies/bat_idle_left.png
assets-cg/enemies/bat_idle_right.png
assets-cg/enemies/bat_death_left.png
assets-cg/enemies/bat_death_right.png
# Misc
assets-cg/font_damage_red.png
assets-cg/font_damage_white.png
assets-cg/font_rogue.png
)
fxconv_declare_assets(${ASSETS} ${ASSETS} WITH_METADATA)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 979 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

View File

@ -3,22 +3,32 @@
name_regex: (.*)\.png anim_\1
profile: p8
# Slime
slime_*.png:
center: 11, 15
slime_idle_down.png:
slime_idle_left.png:
frame_duration: 500, 500
next: anim_slime_idle_down
next: anim_slime_idle_left
slime_idle_right.png:
frame_duration: 500, 500
next: anim_slime_idle_right
slime_death.png:
slime_death_*.png:
frame_duration: 100, 100, 100
# Bat
bat_*.png:
center: 12, 12
bat_idle_down.png:
bat_idle_left.png:
frame_duration: 50, 100, 50, 100, 100
next: anim_bat_idle_down
next: anim_bat_idle_left
bat_idle_right.png:
frame_duration: 50, 100, 50, 100, 100
next: anim_bat_idle_right
bat_death.png:
bat_death_*.png:
frame_duration: 100, 100, 100, 100

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

BIN
assets-cg/font_rogue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -2,3 +2,13 @@
type: bopti-image
name_regex: (.*)\.png img_\1
profile: p8
font_rogue.png:
type: font
name: font_rogue
charset: print
grid.size: 10x13
grid.padding: 0
grid.border: 0
proportional: true
height: 9

View File

@ -48,13 +48,19 @@ void anim_state_update(anim_state_t *state, fixed_t dt);
/* List of animations. */
/* Basic animations. */
extern anim_frame_t anim_slime_idle_down[];
extern anim_frame_t anim_slime_death[];
extern anim_frame_t anim_bat_idle_down[];
extern anim_frame_t anim_bat_death[];
extern anim_frame_t anim_hit[];
/* Directional animations. */
/* Enemy animations (bidirectional). */
extern anim_frame_t anim_slime_idle_left[];
extern anim_frame_t anim_slime_idle_right[];
extern anim_frame_t anim_slime_death_left[];
extern anim_frame_t anim_slime_death_right[];
extern anim_frame_t anim_bat_idle_left[];
extern anim_frame_t anim_bat_idle_right[];
extern anim_frame_t anim_bat_death_left[];
extern anim_frame_t anim_bat_death_right[];
/* Quadri-directional animations. */
extern anim_frame_t *anim_player_idle[4];
extern anim_frame_t *anim_player_attack[4];
extern anim_frame_t *anim_swing[4];

View File

@ -6,8 +6,8 @@ static enemy_t const slime = {
.name = "Slime",
.hitbox = (frect_t){ -FIX(3)/16, FIX(4)/16, -FIX(2)/16, FIX(3)/16 },
.sprite = (frect_t){ -FIX(5)/16, FIX(5)/16, -FIX(4)/16, FIX(3)/16 },
.anim_idle = anim_slime_idle_down,
.anim_death = anim_slime_death,
.anim_idle = { anim_slime_idle_left, anim_slime_idle_right },
.anim_death = { anim_slime_death_left, anim_slime_death_right },
.movement_params = {
.max_speed = FIX(1),
.propulsion = FIX(12),
@ -33,8 +33,8 @@ static enemy_t const bat = {
.name = "Bat",
.hitbox = (frect_t){ -FIX(3)/16, FIX(4)/16, -FIX(2)/16, FIX(3)/16 },
.sprite = (frect_t){ -FIX(5)/16, FIX(5)/16, -FIX(4)/16, FIX(3)/16 },
.anim_idle = anim_bat_idle_down,
.anim_death = anim_bat_death,
.anim_idle = { anim_bat_idle_left, anim_bat_idle_right },
.anim_death = { anim_bat_death_left, anim_bat_death_right },
.movement_params = {
.max_speed = FIX(2),
.propulsion = FIX(8),
@ -87,12 +87,12 @@ entity_t *enemy_spawn(int enemy_id, int level)
e->movement.y = 0;
e->movement.vx = 0;
e->movement.vy = 0;
e->movement.facing = DOWN;
e->movement.facing = LEFT;
e->movement.dash = 0;
e->movement.dash_facing = DOWN;
e->movement.dash_facing = LEFT;
e->movement_params = &data->movement_params;
entity_set_anim(e, data->anim_idle);
entity_set_anim(e, data->anim_idle[0]);
e->hitbox = data->hitbox;
e->sprite = data->sprite;

View File

@ -28,7 +28,7 @@ typedef struct {
/* Sprite hitbox (interacts with attacks and effect areas) */
frect_t sprite;
/* Idle animation, death animation */
anim_frame_t *anim_idle, *anim_death;
anim_frame_t *anim_idle[2], *anim_death[2];
/* Movement parameters */
entity_movement_params_t movement_params;
/* Statistics model */

View File

@ -148,7 +148,8 @@ int entity_damage(entity_t *e, int base_damage)
else e->HP -= damage;
if(e->HP == 0 && e->identity > 0) {
entity_set_anim(e, enemies[e->identity]->anim_death);
entity_set_anim(e,
enemies[e->identity]->anim_death[e->movement.facing == RIGHT]);
}
return damage;

View File

@ -36,6 +36,8 @@ bool game_load(game_t *g, level_t *level)
g->effect_area_count = 0;
g->particles = NULL;
g->particle_count = 0;
g->wave = 1;
return true;
}

View File

@ -35,6 +35,8 @@ typedef struct game {
int particle_count;
/* Field of movement to reach the player (used by most enemy AIs) */
pfg_all2one_t paths_to_player;
/* Current wave */
int wave;
} game_t;

View File

@ -70,7 +70,7 @@ int main(void)
.propulsion = fix(12),
.dash_speed = fix(55),
.dash_duration = fix(1) / 32,
.dash_cooldown = fix(1) / 2,
.dash_cooldown = fix(1),
};
for(int i = 0; i < 10; i++) {
@ -132,11 +132,11 @@ int main(void)
dclear(C_BLACK);
render_game(&game, debug.show_hitboxes);
if(game.time_victory != 0) dprint(1, 1, C_WHITE, "Victory in %.1f s!",
/* if(game.time_victory != 0) dprint(1, 1, C_WHITE, "Victory in %.1f s!",
f2double(game.time_victory));
else if(game.time_defeat != 0) dprint(1, 1, C_WHITE, "Defeat! :(");
else dprint(1, 1, C_WHITE, "HP:%d ATK:%d DEF:%d",
player->HP, player->ATK, player->DEF);
player->HP, player->ATK, player->DEF); */
/* Developer/tweaking menu */
if(debug.show_vars) {
@ -386,7 +386,15 @@ int main(void)
}
entity_movement_t next = entity_move(e, direction, dt);
if(direction.x > 0) next.facing = RIGHT;
else if(direction.x < 0) next.facing = LEFT;
else if(e->movement.x < player->movement.x) next.facing = RIGHT;
else next.facing = LEFT;
bool set_anim = (e->movement.facing != next.facing);
game_try_move_entity(&game, e, &next);
if(set_anim) entity_set_anim(e,
enemies[e->identity]->anim_idle[e->movement.facing == RIGHT]);
if(in_range && !e->current_attack) {
/* Attack */

View File

@ -197,6 +197,23 @@ void render_game(game_t const *g, bool show_hitboxes)
particle_render(center.x, center.y, p);
}
extern font_t font_rogue;
font_t const *old_font = dfont(&font_rogue);
/* Render wave progress bar */
int enemies_left = 0;
for(int i = 0; i < g->entity_count; i++)
enemies_left += (g->entities[i]->identity != 0);
if(enemies_left > 0)
dprint_opt(DWIDTH / 2, 2, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Wave %d: %d enemies left", g->wave, enemies_left);
else
dprint_opt(DWIDTH / 2, 2, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Wave %d: Victory!", g->wave);
dfont(old_font);
}
void render_pfg_all2one(pfg_all2one_t const *paths, camera_t const *c)