more test waves, preparing skills, better HUD

This commit is contained in:
Lephenixnoir 2021-10-23 15:10:20 +02:00
parent fec8e3cab4
commit 8bca321d0f
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
10 changed files with 83 additions and 26 deletions

View File

@ -36,10 +36,10 @@ set(ASSETS
assets-cg/levels/demo.txt
assets-cg/levels/1.txt
# HUD
assets-cg/hud.png
assets-cg/hud_life.png
assets-cg/hud_wave.png
assets-cg/hud_wave2.png
assets-cg/hud_life.png
assets-cg/hud_life2.png
assets-cg/skillicons.png
# Player animations
assets-cg/player/player_up.aseprite

BIN
assets-cg/hud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 845 B

After

Width:  |  Height:  |  Size: 540 B

View File

@ -49,6 +49,10 @@ typedef struct {
uint8_t combo_next;
/* Delay until ideal time to start next hit */
fixed_t combo_delay;
/* Skill and item cooldowns (F2..F5).The "total" field is updated when
switching skills/items. The base field is the dynamic value. */
fixed_t actions_cooldown_total[5];
fixed_t actions_cooldown[5];
} entity_player_t;

View File

@ -79,6 +79,7 @@ void game_next_wave(game_t *g)
g->wave++;
g->wave_spawned = 0;
g->time_wave = fix(0);
g->time_victory = fix(0);
}
//---

View File

@ -9,9 +9,23 @@ level_t lv_demo = {
.map = &lv_map_demo,
};
/* Notation that would be very cool:
- slime/1 ;
| slime/1 ;
slime/1 ;
| slime/1 ;
slime/2 ;
| slime/2 ;
- slime/2 | slime/2 ;
bat/1 | bat/1 ;
Each - bullet is a wave, with ';' separating "instants". Default is
increments of 0.5 unless specified otherwise or @<time> */
level_t lv_1 = {
.map = &lv_map_1,
.wave_count = 2,
.wave_count = 5,
.waves = (level_wave_t []){
/* Wave 1: Just some slimes */
{ .enemy_count = 6,
@ -31,5 +45,34 @@ level_t lv_1 = {
{ ENEMY_BAT, 1, 2,1, fix(1.0) },
{ ENEMY_BAT, 1, 19,9, fix(1.0) },
}},
/* Wave 3: Strong, fast bats */
{ .enemy_count = 4,
.enemies = (level_wave_spawn_t []) {
{ ENEMY_BAT, 2, 2,1, fix(0.0) },
{ ENEMY_BAT, 2, 19,9, fix(0.5) },
{ ENEMY_BAT, 2, 2,1, fix(1.0) },
{ ENEMY_BAT, 2, 19,9, fix(1.5) },
}},
/* Wave 4: A hurl of slimes, with bats to harass you */
{ .enemy_count = 12,
.enemies = (level_wave_spawn_t []) {
{ ENEMY_SLIME, 2, 2,1, fix(0.00) },
{ ENEMY_SLIME, 2, 19,9, fix(0.00) },
{ ENEMY_SLIME, 2, 2,1, fix(0.25) },
{ ENEMY_SLIME, 2, 19,9, fix(0.25) },
{ ENEMY_SLIME, 2, 2,1, fix(0.50) },
{ ENEMY_SLIME, 2, 19,9, fix(0.50) },
{ ENEMY_SLIME, 2, 2,1, fix(0.75) },
{ ENEMY_SLIME, 2, 19,9, fix(0.75) },
{ ENEMY_SLIME, 2, 2,1, fix(1.00) },
{ ENEMY_SLIME, 2, 19,9, fix(1.00) },
{ ENEMY_BAT, 3, 2,1, fix(2.00) },
{ ENEMY_BAT, 3, 19,9, fix(2.00) },
}},
/* Wave 5: Stronger first boss */
{ .enemy_count = 1,
.enemies = (level_wave_spawn_t []) {
{ ENEMY_BAT, 5, 2,1, fix(0.0) },
}},
},
};

View File

@ -477,6 +477,17 @@ int main(void)
player->current_attack = area;
player->attack_follows_movement = false;
}
/* Ideas for additional skills:
- Freeze enemies
- Barrier around player
- Teleport
- Time manipulation
- Player buuffs (short but strong) or wide area debuggs
Ideas for items:
- Healing potion
- Equipment
- XP boosts
- Weaker but longer-lasting buffs */
/* Remove dead entities first as it will kill their attack areas */
game_remove_dead_entities(&game);

View File

@ -29,8 +29,8 @@ void camera_init(camera_t *c, map_t const *m)
c->x = (c->limits.x_min + c->limits.x_max) / 2;
c->y = (c->limits.y_min + c->limits.y_max) / 2;
/* Slightly off-center to add space for the HUD */
c->y -= fix(0.375);
/* Vertical adjustment to add space for the HUD */
c->y -= fix(0);
}
ipoint_t camera_map2screen(camera_t const *c, fpoint_t p)
@ -226,32 +226,27 @@ void render_game(game_t const *g, bool show_hitboxes)
for(int i = 0; i < g->entity_count; i++)
enemies_left += (g->entities[i]->identity != 0);
extern bopti_image_t img_hud_wave, img_hud_wave2;
dimage(DWIDTH - img_hud_wave.width, 17, &img_hud_wave);
int fill_length = (img_hud_wave2.width * enemies_left) /
g->level->waves[g->wave-1].enemy_count;
dsubimage(DWIDTH - fill_length, 17, &img_hud_wave2,
img_hud_wave2.width - fill_length, 0, fill_length,
img_hud_wave2.height, DIMAGE_NONE);
if(g->wave_spawned < game_current_wave(g)->enemy_count)
dprint_opt(DWIDTH - 4, 2, C_WHITE, C_NONE, DTEXT_RIGHT, DTEXT_TOP,
dprint_opt(DWIDTH/2, 2, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Wave %d is preppin' up...", g->wave,
game_current_wave(g)->enemy_count - g->wave_spawned);
else if(enemies_left > 0)
dprint_opt(DWIDTH - 4, 2, C_WHITE, C_NONE, DTEXT_RIGHT, DTEXT_TOP,
dprint_opt(DWIDTH/2, 2, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Wave %d is here for you!", g->wave, enemies_left);
else
dprint_opt(DWIDTH - 4, 2, C_WHITE, C_NONE, DTEXT_RIGHT, DTEXT_TOP,
dprint_opt(DWIDTH/2, 2, C_WHITE, C_NONE, DTEXT_CENTER, DTEXT_TOP,
"Victory! For now...", g->wave);
entity_t const *player = g->player;
dprint(2, 2, C_WHITE, "HP: %d/%d", player->HP, player->HP_max);
/* Render HUD */
extern bopti_image_t img_hud;
dimage(0, DHEIGHT - img_hud.height, &img_hud);
extern bopti_image_t img_hud_life, img_hud_life2;
dimage(0, 17, &img_hud_life);
fill_length = (img_hud_life2.width * player->HP) / player->HP_max;
dsubimage(0, 17, &img_hud_life2, 0, 0, fill_length, img_hud_life2.height,
/* Render life bar */
extern bopti_image_t img_hud_life;
entity_t const *player = g->player;
int fill_height = (img_hud_life.height * player->HP) / player->HP_max;
dsubimage(184, DHEIGHT - 5 - fill_height, &img_hud_life,
0, img_hud_life.height - fill_height, img_hud_life.width, fill_height,
DIMAGE_NONE);
/* Render skill icons */
@ -264,12 +259,15 @@ void render_game(game_t const *g, bool show_hitboxes)
cooldown_remaining = -player->movement.dash;
}
else if(i > 0) {
cooldown_remaining=fix(1);
cooldown_total = player->player->actions_cooldown_total[i-1];
cooldown_remaining = player->player->actions_cooldown[i-1];
}
int x=15+68*i, y=DHEIGHT-27, bg=(cooldown_remaining!=0);
dsubimage(x, y, &img_skillicons, 23*bg, 0, 23, 23, DIMAGE_NONE);
dsubimage(x, y, &img_skillicons, 23*(i+2), 0, 23, 23, DIMAGE_NONE);
int x = 33 + 44*i + 84*(i>=3);
int y = DHEIGHT - 29;
int bg = (cooldown_remaining != 0);
dsubimage(x+2, y+2, &img_skillicons, 19*bg, 0, 19, 19, DIMAGE_NONE);
dsubimage(x+2, y+2, &img_skillicons, 19*(i+2), 0, 19, 19, DIMAGE_NONE);
/* Darken the area representing remaining cooldown */
if(cooldown_total != 0) {