diff --git a/CMakeLists.txt b/CMakeLists.txt index f85c045..18a8899 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/assets-cg/enemies/bat_death.aseprite b/assets-cg/enemies/bat_death.aseprite deleted file mode 100644 index 251c57e..0000000 Binary files a/assets-cg/enemies/bat_death.aseprite and /dev/null differ diff --git a/assets-cg/enemies/bat_death.png b/assets-cg/enemies/bat_death.png deleted file mode 100644 index abe8a3d..0000000 Binary files a/assets-cg/enemies/bat_death.png and /dev/null differ diff --git a/assets-cg/enemies/bat_death_left.aseprite b/assets-cg/enemies/bat_death_left.aseprite new file mode 100644 index 0000000..fb93137 Binary files /dev/null and b/assets-cg/enemies/bat_death_left.aseprite differ diff --git a/assets-cg/enemies/bat_death_left.png b/assets-cg/enemies/bat_death_left.png new file mode 100644 index 0000000..9af1412 Binary files /dev/null and b/assets-cg/enemies/bat_death_left.png differ diff --git a/assets-cg/enemies/bat_death_right.aseprite b/assets-cg/enemies/bat_death_right.aseprite new file mode 100644 index 0000000..c8cd4f2 Binary files /dev/null and b/assets-cg/enemies/bat_death_right.aseprite differ diff --git a/assets-cg/enemies/bat_death_right.png b/assets-cg/enemies/bat_death_right.png new file mode 100644 index 0000000..846cf86 Binary files /dev/null and b/assets-cg/enemies/bat_death_right.png differ diff --git a/assets-cg/enemies/bat_idle_down.aseprite b/assets-cg/enemies/bat_idle_down.aseprite deleted file mode 100644 index 318044b..0000000 Binary files a/assets-cg/enemies/bat_idle_down.aseprite and /dev/null differ diff --git a/assets-cg/enemies/bat_idle_down.png b/assets-cg/enemies/bat_idle_down.png deleted file mode 100644 index 4f71b6f..0000000 Binary files a/assets-cg/enemies/bat_idle_down.png and /dev/null differ diff --git a/assets-cg/enemies/bat_idle_left.aseprite b/assets-cg/enemies/bat_idle_left.aseprite new file mode 100644 index 0000000..608ca8d Binary files /dev/null and b/assets-cg/enemies/bat_idle_left.aseprite differ diff --git a/assets-cg/enemies/bat_idle_left.png b/assets-cg/enemies/bat_idle_left.png new file mode 100644 index 0000000..0e57118 Binary files /dev/null and b/assets-cg/enemies/bat_idle_left.png differ diff --git a/assets-cg/enemies/bat_idle_right.aseprite b/assets-cg/enemies/bat_idle_right.aseprite new file mode 100644 index 0000000..ef106d0 Binary files /dev/null and b/assets-cg/enemies/bat_idle_right.aseprite differ diff --git a/assets-cg/enemies/bat_idle_right.png b/assets-cg/enemies/bat_idle_right.png new file mode 100644 index 0000000..93f4c01 Binary files /dev/null and b/assets-cg/enemies/bat_idle_right.png differ diff --git a/assets-cg/enemies/fxconv-metadata.txt b/assets-cg/enemies/fxconv-metadata.txt index 468153a..d5f6f69 100644 --- a/assets-cg/enemies/fxconv-metadata.txt +++ b/assets-cg/enemies/fxconv-metadata.txt @@ -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 diff --git a/assets-cg/enemies/slime_death.aseprite b/assets-cg/enemies/slime_death.aseprite deleted file mode 100644 index 51463fd..0000000 Binary files a/assets-cg/enemies/slime_death.aseprite and /dev/null differ diff --git a/assets-cg/enemies/slime_death.png b/assets-cg/enemies/slime_death.png deleted file mode 100644 index 0de7c00..0000000 Binary files a/assets-cg/enemies/slime_death.png and /dev/null differ diff --git a/assets-cg/enemies/slime_death_left.aseprite b/assets-cg/enemies/slime_death_left.aseprite new file mode 100644 index 0000000..a74e078 Binary files /dev/null and b/assets-cg/enemies/slime_death_left.aseprite differ diff --git a/assets-cg/enemies/slime_death_left.png b/assets-cg/enemies/slime_death_left.png new file mode 100644 index 0000000..b5f24a7 Binary files /dev/null and b/assets-cg/enemies/slime_death_left.png differ diff --git a/assets-cg/enemies/slime_death_right.aseprite b/assets-cg/enemies/slime_death_right.aseprite new file mode 100644 index 0000000..a03878e Binary files /dev/null and b/assets-cg/enemies/slime_death_right.aseprite differ diff --git a/assets-cg/enemies/slime_death_right.png b/assets-cg/enemies/slime_death_right.png new file mode 100644 index 0000000..bfb68b3 Binary files /dev/null and b/assets-cg/enemies/slime_death_right.png differ diff --git a/assets-cg/enemies/slime_idle_down.png b/assets-cg/enemies/slime_idle_down.png deleted file mode 100644 index 6c9301d..0000000 Binary files a/assets-cg/enemies/slime_idle_down.png and /dev/null differ diff --git a/assets-cg/enemies/slime_idle_left.aseprite b/assets-cg/enemies/slime_idle_left.aseprite new file mode 100644 index 0000000..357ea08 Binary files /dev/null and b/assets-cg/enemies/slime_idle_left.aseprite differ diff --git a/assets-cg/enemies/slime_idle_left.png b/assets-cg/enemies/slime_idle_left.png new file mode 100644 index 0000000..a1a7d0d Binary files /dev/null and b/assets-cg/enemies/slime_idle_left.png differ diff --git a/assets-cg/enemies/slime_idle_down.aseprite b/assets-cg/enemies/slime_idle_right.aseprite similarity index 62% rename from assets-cg/enemies/slime_idle_down.aseprite rename to assets-cg/enemies/slime_idle_right.aseprite index 36e1901..e1fa33c 100644 Binary files a/assets-cg/enemies/slime_idle_down.aseprite and b/assets-cg/enemies/slime_idle_right.aseprite differ diff --git a/assets-cg/enemies/slime_idle_right.png b/assets-cg/enemies/slime_idle_right.png new file mode 100644 index 0000000..705b4b8 Binary files /dev/null and b/assets-cg/enemies/slime_idle_right.png differ diff --git a/assets-cg/font_rogue.png b/assets-cg/font_rogue.png new file mode 100644 index 0000000..0b49999 Binary files /dev/null and b/assets-cg/font_rogue.png differ diff --git a/assets-cg/fxconv-metadata.txt b/assets-cg/fxconv-metadata.txt index 57e2675..b46e19b 100644 --- a/assets-cg/fxconv-metadata.txt +++ b/assets-cg/fxconv-metadata.txt @@ -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 diff --git a/src/anim.h b/src/anim.h index 6e849d4..b535f42 100644 --- a/src/anim.h +++ b/src/anim.h @@ -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]; diff --git a/src/enemies.c b/src/enemies.c index 5117246..211877e 100644 --- a/src/enemies.c +++ b/src/enemies.c @@ -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; diff --git a/src/enemies.h b/src/enemies.h index 733b638..e3131d7 100644 --- a/src/enemies.h +++ b/src/enemies.h @@ -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 */ diff --git a/src/entities.c b/src/entities.c index ba97266..92940d1 100644 --- a/src/entities.c +++ b/src/entities.c @@ -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; diff --git a/src/game.c b/src/game.c index b78df5a..0ba557d 100644 --- a/src/game.c +++ b/src/game.c @@ -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; } diff --git a/src/game.h b/src/game.h index ee374b1..70a954b 100644 --- a/src/game.h +++ b/src/game.h @@ -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; diff --git a/src/main.c b/src/main.c index d0aadc8..e2faf2c 100644 --- a/src/main.c +++ b/src/main.c @@ -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 */ diff --git a/src/render.c b/src/render.c index 495c9a7..7dde6c6 100644 --- a/src/render.c +++ b/src/render.c @@ -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)