From 40eb179043b77f011fb1048c386ee187f64569d0 Mon Sep 17 00:00:00 2001 From: quou Date: Sun, 7 May 2023 09:37:45 +1000 Subject: Add waves and some more polish. --- Makefile | 1 + animation.c | 13 ++++++++++++ animation.h | 3 ++- collision_system.c | 2 +- config.h | 3 +++ enemy.c | 2 ++ fx.c | 35 ++++++++++++++++++++++++++++---- fx.h | 6 ++++++ game.c | 7 ++++--- game_config.h | 1 + intermediate/usr.bmp | Bin 75378 -> 75378 bytes player.c | 36 ++++++++++++++++++++++++++++++++- player.h | 7 ++++++- wave.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ wave.h | 36 +++++++++++++++++++++++++++++++++ world.c | 3 +++ world.h | 4 ++++ 17 files changed, 204 insertions(+), 11 deletions(-) create mode 100644 wave.c create mode 100644 wave.h diff --git a/Makefile b/Makefile index 44b9fa3..715391a 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,7 @@ sources = \ sprite.c \ sprite_system.c \ standard.c \ + wave.c \ world.c \ diff --git a/animation.c b/animation.c index a0fea2c..ff944eb 100644 --- a/animation.c +++ b/animation.c @@ -66,6 +66,19 @@ static const Animation animations[] = { }, 7, 1 + }, + /* animation_heart_break */ + { + { + { 72, 72, 7, 7 }, + { 79, 72, 7, 7 }, + { 86, 72, 7, 7 }, + { 93, 72, 7, 7 }, + { 100, 72, 7, 7 }, + { 107, 72, 7, 7 } + }, + 6, + 3 } }; diff --git a/animation.h b/animation.h index e132202..0a36043 100644 --- a/animation.h +++ b/animation.h @@ -10,7 +10,8 @@ typedef enum { animation_player_idle_left, animation_player_idle_right, animation_enemy_bullet_explode, - animation_player_bullet_explode + animation_player_bullet_explode, + animation_heart_break } Animation_ID; typedef struct { diff --git a/collision_system.c b/collision_system.c index cf1378c..ed05817 100644 --- a/collision_system.c +++ b/collision_system.c @@ -47,7 +47,7 @@ static void handle_bullet_vs_player( pos = &world->positions[bullet]; - player_take_damage(&world->player, 1); + player_take_damage(world, &world->player, 1); destroy_entity(world, bullet); new_enemy_bullet_explosion(world, pos->x, pos->y); } diff --git a/config.h b/config.h index 51a559a..4465d68 100644 --- a/config.h +++ b/config.h @@ -21,4 +21,7 @@ #define menu_max_elements 4 +#define wave_max_subwaves 8 +#define wave_max_spawns 16 + #endif diff --git a/enemy.c b/enemy.c index 332a769..710a280 100644 --- a/enemy.c +++ b/enemy.c @@ -42,6 +42,8 @@ Entity new_skull(World* world, int x, int y) { enemy->hp = skull_hp; enemy->shoot_timer = 0; + world->enemy_count++; + return e; } diff --git a/fx.c b/fx.c index 53670b4..8e0e41f 100644 --- a/fx.c +++ b/fx.c @@ -6,7 +6,8 @@ static int new_fx( World* world, int x, int y, - Animation_ID anim + Animation_ID anim, + Asset_ID bitmap ) { Entity e; CPosition* pos; @@ -30,7 +31,7 @@ static int new_fx( pos->x = x; pos->y = y; - sprite->id = asset_id_bullet; + sprite->id = bitmap; sprite->rect = make_rect(0, 0, 16, 16); animated->id = anim; @@ -45,7 +46,13 @@ int new_enemy_bullet_explosion( int x, int y ) { - return new_fx(world, x, y, animation_enemy_bullet_explode); + return new_fx( + world, + x, + y, + animation_enemy_bullet_explode, + asset_id_bullet + ); } int new_player_bullet_explosion( @@ -53,5 +60,25 @@ int new_player_bullet_explosion( int x, int y ) { - return new_fx(world, x, y, animation_player_bullet_explode); + return new_fx( + world, + x, + y, + animation_player_bullet_explode, + asset_id_bullet + ); +} + +int new_heart_break( + struct World* world, + int x, + int y +) { + return new_fx( + world, + x, + y, + animation_heart_break, + asset_id_usr + ); } diff --git a/fx.h b/fx.h index dff8c47..91ab4e6 100644 --- a/fx.h +++ b/fx.h @@ -17,4 +17,10 @@ int new_player_bullet_explosion( int y ); +int new_heart_break( + struct World* world, + int x, + int y +); + #endif diff --git a/game.c b/game.c index f5edb8a..b68d85a 100644 --- a/game.c +++ b/game.c @@ -45,8 +45,7 @@ static void menu_init(Game* game) { font = get_default_font(); init_menu(&game->menu, game); - menu_add(&game->menu, "New", menu_new, font); - menu_add(&game->menu, "Continue", 0, font); + menu_add(&game->menu, "Play", menu_new, font); menu_add(&game->menu, "Credits", menu_credits, font); menu_add(&game->menu, "Quit", menu_quit, font); } @@ -104,7 +103,7 @@ static void gameplay_init(Game* game) { init_world(&game->world); init_map(&world->map, world); init_player(&world->player, world); - new_skull(world, 0, 0); + init_waver(&world->waver); world->gmemory = gmemory_max; } @@ -174,6 +173,8 @@ static void gameplay_update(Game* game) { world = &game->world; player = &world->player; + update_waver(&world->waver, world); + update_player(player, world); enemy_system(world); debris_system(world); diff --git a/game_config.h b/game_config.h index 5094cf8..4e955a9 100644 --- a/game_config.h +++ b/game_config.h @@ -4,6 +4,7 @@ #define player_move_speed (3 << fbits) #define player_bullet_speed (10 << fbits) #define player_max_hp 3 +#define player_invul_frames 50 #define skull_hp 3 #define skull_speed (1 << fbits) diff --git a/intermediate/usr.bmp b/intermediate/usr.bmp index b8bcd09..c0eecc2 100644 Binary files a/intermediate/usr.bmp and b/intermediate/usr.bmp differ diff --git a/player.c b/player.c index 7135557..ff3f53b 100644 --- a/player.c +++ b/player.c @@ -1,6 +1,7 @@ #include "animation.h" #include "bullet.h" #include "components.h" +#include "fx.h" #include "game.h" #include "game_config.h" #include "input.h" @@ -129,6 +130,22 @@ void update_player(Player* player, World* world) { player->shoot_countdown = player->shoot_cooldown; } + if (player->invul) { + player->invul--; + player->invul_counter++; + + if (player->invul_counter > 3) { + if (world->bitmask[e] & ctype_sprite) { + world->bitmask[e] &= ~ctype_sprite; + } else { + world->bitmask[e] |= ctype_sprite; + } + player->invul_counter = 0; + } + } else { + world->bitmask[e] |= ctype_sprite; + } + if (player->hp <= 0) { world->oom = 0; game_change_state(&game, game_state_dead); @@ -137,8 +154,25 @@ void update_player(Player* player, World* world) { player->shoot_countdown--; } -void player_take_damage(Player* player, int dmg) { +void player_take_damage( + World* world, + Player* player, + int dmg +) { + const CPosition* pos; + + pos = &world->positions[player->entity]; + + if (player->invul) { return; } + player->hp -= dmg; + player->invul = player_invul_frames; + player->invul_counter = 0; + new_heart_break( + world, + pos->x + (4 << fbits), + pos->y - (8 << fbits) + ); } void update_camera(Player* player, World* world) { diff --git a/player.h b/player.h index 0fb3e4d..86a0426 100644 --- a/player.h +++ b/player.h @@ -10,11 +10,16 @@ typedef struct { int shoot_cooldown; int shoot_countdown; int hp; + int invul, invul_counter; } Player; void init_player(Player* player, struct World* world); void update_player(Player* player, struct World* world); -void player_take_damage(Player* player, int dmg); +void player_take_damage( + struct World* world, + Player* player, + int dmg +); void update_camera(Player* player, struct World* world); #endif diff --git a/wave.c b/wave.c new file mode 100644 index 0000000..93b43f4 --- /dev/null +++ b/wave.c @@ -0,0 +1,56 @@ +#include "enemy.h" +#include "standard.h" +#include "wave.h" +#include "world.h" + +static const Wave waves[] = { + { + { + { + 20, + 2, + { + { 3, 5 }, + { 15, 15 }, + } + }, + }, + 1 + } +}; + +void init_waver(Waver* waver) { + waver->idx = 0; + waver->sidx = 0; + waver->timer = 0; +} + +void next_wave(Waver* waver) { + waver->idx++; +} + +void update_waver(Waver* waver, World* world) { + const Wave* wave; + const Subwave* subwave; + const Wave_Spawn* spawn; + int i; + + wave = &waves[waver->idx]; + subwave = &wave->subwaves[waver->sidx]; + + if (waver->sidx >= wave->subwave_count) { return; } + + waver->timer++; + + if (waver->timer >= subwave->frame) { + for (i = 0; i < subwave->count; i++) { + spawn = &subwave->spawns[i]; + new_skull( + world, + (spawn->x * map_tile_size) << fbits, + (spawn->y * map_tile_size) << fbits + ); + } + waver->sidx++; + } +} diff --git a/wave.h b/wave.h new file mode 100644 index 0000000..3d40981 --- /dev/null +++ b/wave.h @@ -0,0 +1,36 @@ +#ifndef wave_h +#define wave_h + +#include "config.h" + +/* TODO: Different enemies. */ + +typedef struct Waver Waver; + +typedef void (*Wave_Finish)(Waver* waver, int last); + +typedef struct { + int x, y; +} Wave_Spawn; + +typedef struct { + int frame; + int count; + Wave_Spawn spawns[wave_max_spawns]; +} Subwave; + +typedef struct { + Subwave subwaves[wave_max_subwaves]; + int subwave_count; +} Wave; + +struct Waver { + int idx, sidx; + int timer; +}; + +void init_waver(Waver* waver); +void next_wave(Waver* waver); +void update_waver(Waver* waver, struct World* world); + +#endif diff --git a/world.c b/world.c index 4995351..3ee369d 100644 --- a/world.c +++ b/world.c @@ -36,6 +36,9 @@ Entity new_entity(World* world) { void destroy_entity(World* world, Entity e) { world->recycle_bin[world->recycle_bin_count++] = e; + if (world->bitmask[e] & ctype_enemy) { + world->enemy_count--; + } world->bitmask[e] = 0; world->gmemory++; } diff --git a/world.h b/world.h index 5f324a8..6749dbc 100644 --- a/world.h +++ b/world.h @@ -5,11 +5,13 @@ #include "config.h" #include "map.h" #include "player.h" +#include "wave.h" typedef int Entity; typedef struct World World; +/* Keep as POD. */ struct World { int entity_count; int recycle_bin_count; @@ -27,8 +29,10 @@ struct World { Player player; Map map; + Waver waver; int cam_x, cam_y; + int enemy_count; int gmemory, oom; }; -- cgit v1.2.3-54-g00ecf