aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2023-05-07 09:37:45 +1000
committerquou <quou@disroot.org>2023-05-07 09:37:45 +1000
commit40eb179043b77f011fb1048c386ee187f64569d0 (patch)
treeebae794ec0b3b8851b8c29119ada06555f49d4b6
parent47e7976922f5c17505c7c5a3377c3735649e3dcc (diff)
Add waves and some more polish.
-rw-r--r--Makefile1
-rw-r--r--animation.c13
-rw-r--r--animation.h3
-rw-r--r--collision_system.c2
-rw-r--r--config.h3
-rw-r--r--enemy.c2
-rw-r--r--fx.c35
-rw-r--r--fx.h6
-rw-r--r--game.c7
-rw-r--r--game_config.h1
-rw-r--r--intermediate/usr.bmpbin75378 -> 75378 bytes
-rw-r--r--player.c36
-rw-r--r--player.h7
-rw-r--r--wave.c56
-rw-r--r--wave.h36
-rw-r--r--world.c3
-rw-r--r--world.h4
17 files changed, 204 insertions, 11 deletions
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
--- a/intermediate/usr.bmp
+++ b/intermediate/usr.bmp
Binary files 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;
};