aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2023-05-05 09:25:39 +1000
committerquou <quou@disroot.org>2023-05-05 09:25:39 +1000
commit280552fa4750b5dac9243782f9c0a7e0b7eea6f8 (patch)
tree6385dc740cc965dad7dc628e8b10738724ec0a42
parent0a083f5a9a747083bbc3a1f0689e76ac5fc3a3b9 (diff)
Add a basic enemy.
-rw-r--r--Makefile1
-rw-r--r--asset.c3
-rw-r--r--asset.h3
-rw-r--r--bullet.c37
-rw-r--r--bullet.h8
-rw-r--r--components.h15
-rw-r--r--enemy.c103
-rw-r--r--enemy.h8
-rw-r--r--game_config.h6
-rw-r--r--intermediate/enemy.bmpbin0 -> 8330 bytes
-rw-r--r--main.c4
-rw-r--r--player.c4
-rw-r--r--sprite.c40
-rw-r--r--sprite.h10
-rw-r--r--standard.c14
-rw-r--r--standard.h4
-rw-r--r--systems.h2
-rw-r--r--world.h3
18 files changed, 258 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index 02a40ff..581c027 100644
--- a/Makefile
+++ b/Makefile
@@ -89,6 +89,7 @@ sources = \
animation_system.c \
asset.c \
bullet.c \
+ enemy.c \
main.c \
malware.c \
platform.c \
diff --git a/asset.c b/asset.c
index b6e408b..5ae5419 100644
--- a/asset.c
+++ b/asset.c
@@ -8,7 +8,8 @@
static const char* const asset_vpaths[] = {
/* asset_id_usr */ "data/usr.img",
/* asset_id_char */ "data/char.img",
- /* asset_id_bullet */ "data/bullet.img"
+ /* asset_id_bullet */ "data/bullet.img",
+ /* asset_id_enemy */ "data/enemy.img"
};
static struct {
diff --git a/asset.h b/asset.h
index e60ff4b..8c6e201 100644
--- a/asset.h
+++ b/asset.h
@@ -3,12 +3,13 @@
#include "render.h"
-#define bitmap_asset_count 3
+#define bitmap_asset_count 4
typedef enum {
asset_id_usr = 0,
asset_id_char,
asset_id_bullet,
+ asset_id_enemy,
asset_count
} Asset_ID;
diff --git a/bullet.c b/bullet.c
index 9acefc2..a2f1c66 100644
--- a/bullet.c
+++ b/bullet.c
@@ -60,6 +60,43 @@ Entity new_player_bullet(
return e;
}
+int new_enemy_bullet(
+ struct World* world,
+ int x,
+ int y,
+ int vx,
+ int vy
+) {
+ Entity e;
+ CBullet* bullet;
+ CPosition* pos;
+ CSprite* sprite;
+
+ e = new_entity(world);
+
+ add_components(
+ world,
+ e,
+ ctype_sprite |
+ ctype_position |
+ ctype_bullet |
+ ctype_enemy_bullet
+ );
+ pos = &world->positions[e];
+ sprite = &world->sprites[e];
+ bullet = &world->bullets[e];
+ pos->x = x;
+ pos->y = y;
+
+ bullet->vx = vx;
+ bullet->vy = vy;
+ bullet->life = 500;
+
+ init_csprite(sprite, sprite_enemy_bullet);
+
+ return e;
+}
+
void bullet_system(World* world) {
int i;
unsigned bits;
diff --git a/bullet.h b/bullet.h
index cd7a436..2c84840 100644
--- a/bullet.h
+++ b/bullet.h
@@ -12,4 +12,12 @@ int new_player_bullet(
int life
);
+int new_enemy_bullet(
+ struct World* world,
+ int x,
+ int y,
+ int vx,
+ int vy
+);
+
#endif
diff --git a/components.h b/components.h
index 66304df..d288ac5 100644
--- a/components.h
+++ b/components.h
@@ -29,13 +29,26 @@ typedef struct {
int vx, vy;
} CBullet;
+typedef struct {
+ int hp;
+ int backpedal;
+ int shoot_timer;
+} CEnemy;
+
+typedef struct {
+ int vx, vy;
+} CDebris;
+
typedef enum {
ctype_sprite = 1 << 0,
ctype_position = 1 << 1,
ctype_animated = 1 << 2,
ctype_bullet = 1 << 3,
ctype_player_bullet = 1 << 4,
- ctype_enemy_bullet = 1 << 5
+ ctype_enemy_bullet = 1 << 5,
+ ctype_enemy = 1 << 6,
+ ctype_skull = 1 << 7,
+ ctype_debris = 1 << 8
} CType;
#endif
diff --git a/enemy.c b/enemy.c
new file mode 100644
index 0000000..9a67cba
--- /dev/null
+++ b/enemy.c
@@ -0,0 +1,103 @@
+#include "bullet.h"
+#include "components.h"
+#include "game_config.h"
+#include "sprite.h"
+#include "standard.h"
+#include "world.h"
+
+Entity new_skull(World* world, int x, int y) {
+ CSprite* sprite;
+ CPosition* pos;
+ CEnemy* enemy;
+ Entity e;
+
+ e = new_entity(world);
+ add_components(
+ world,
+ e,
+ ctype_position |
+ ctype_sprite |
+ ctype_enemy |
+ ctype_skull
+ );
+ pos = &world->positions[e];
+ sprite = &world->sprites[e];
+ enemy = &world->enemies[e];
+
+ pos->x = x;
+ pos->y = y;
+
+ init_csprite(sprite, sprite_skull_right);
+
+ enemy->hp = skull_hp;
+ enemy->shoot_timer = 0;
+
+ return e;
+}
+
+void enemy_system(World* world) {
+ /* Skulls. */
+ int i;
+ unsigned bits;
+ CPosition* pos;
+ CEnemy* enemy;
+ Player* player;
+ CPosition* ppos;
+ int dpx, dpy, tpx, tpy, d;
+ char buf[32];
+
+ player = &world->player;
+ ppos = &world->positions[player->entity];
+
+ for (i = 0; i < world->entity_count; i++) {
+ bits = world->bitmask[i];
+ if (
+ (bits & ctype_position) &&
+ (bits & ctype_enemy) &&
+ (bits & ctype_skull)
+ ) {
+ pos = &world->positions[i];
+ enemy = &world->enemies[i];
+
+ dpx = (ppos->x - pos->x) >> 4;
+ dpy = (ppos->y - pos->y) >> 4;
+ tpx = dpx;
+ tpy = dpy;
+ d = ((dpx * dpx) >> fbits) + ((dpy * dpy) >> fbits);
+
+ if (d < 10 << fbits) {
+ dpx = -dpx;
+ dpy = -dpy;
+ enemy->backpedal = 1;
+ } else if (enemy->backpedal) {
+ if (d > 30 << fbits) {
+ enemy->backpedal = 0;
+ } else {
+ dpx = -dpx;
+ dpy = -dpy;
+ }
+ }
+
+ dpx = (dpx < 0 ? -1 : 1);
+ dpy = (dpy < 0 ? -1 : 1);
+
+ pos->x += dpx * skull_speed;
+ pos->y += dpy * skull_speed;
+
+ if (enemy->shoot_timer > skull_shoot_cooldown) {
+ vec_nrmise(&tpx, &tpy);
+
+ new_enemy_bullet(
+ world,
+ pos->x,
+ pos->y,
+ tpx * enemy_bullet_speed,
+ tpy * enemy_bullet_speed
+ );
+ enemy->shoot_timer = 0;
+ }
+
+ enemy->shoot_timer++;
+ }
+ }
+}
diff --git a/enemy.h b/enemy.h
new file mode 100644
index 0000000..f968864
--- /dev/null
+++ b/enemy.h
@@ -0,0 +1,8 @@
+#ifndef enemy_h
+#define enemy_h
+
+struct World;
+
+int new_skull(struct World* world, int x, int y);
+
+#endif
diff --git a/game_config.h b/game_config.h
index 7bb6cdd..0c97a8d 100644
--- a/game_config.h
+++ b/game_config.h
@@ -4,4 +4,10 @@
#define player_move_speed (3 << fbits)
#define player_bullet_speed (10 << fbits)
+#define skull_hp 3
+#define skull_speed (1 << fbits)
+
+#define skull_shoot_cooldown 15
+#define enemy_bullet_speed 10
+
#endif
diff --git a/intermediate/enemy.bmp b/intermediate/enemy.bmp
new file mode 100644
index 0000000..da1e068
--- /dev/null
+++ b/intermediate/enemy.bmp
Binary files differ
diff --git a/main.c b/main.c
index e1fd29b..ef757b2 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,7 @@
#include "standard.h"
#include "systems.h"
#include "world.h"
+#include "enemy.h"
World world;
@@ -17,11 +18,14 @@ void on_init(int argc, char** argv) {
init_world(&world);
init_player(&world.player, &world);
+
+ new_skull(&world, 0, 0);
}
void on_update() {
renderer_begin_frame();
update_player(&world.player, &world);
+ enemy_system(&world);
bullet_system(&world);
animation_system(&world);
sprite_system(&world);
diff --git a/player.c b/player.c
index cadb0dc..b723849 100644
--- a/player.c
+++ b/player.c
@@ -26,8 +26,8 @@ void init_player(Player* player, World* world) {
sprite = &world->sprites[e];
animated = &world->animateds[e];
- pos->x = 32;
- pos->y = 70;
+ pos->x = 32 << fbits;
+ pos->y = 70 << fbits;
sprite->id = asset_id_char;
sprite->rect = make_rect(0, 16, 16, 16);
diff --git a/sprite.c b/sprite.c
index 8289fd2..c14f717 100644
--- a/sprite.c
+++ b/sprite.c
@@ -20,6 +20,46 @@ static const Sprite sprites[] = {
{
asset_id_bullet,
{ 14, 14, 14, 9 }
+ },
+ /* sprite_skull_left */
+ {
+ asset_id_enemy,
+ { 16, 0, 16, 16 }
+ },
+ /* sprite_skull_right */
+ {
+ asset_id_enemy,
+ { 0, 0, 16, 16 }
+ },
+ /* sprite_skull_debris_1 */
+ {
+ asset_id_enemy,
+ { 32, 0, 5, 8 }
+ },
+ /* sprite_skull_debris_2 */
+ {
+ asset_id_enemy,
+ { 38, 0, 6, 6 }
+ },
+ /* sprite_skull_debris_3 */
+ {
+ asset_id_enemy,
+ { 32, 8, 5, 8 }
+ },
+ /* sprite_skull_debris_4 */
+ {
+ asset_id_enemy,
+ { 38, 11, 5, 5 }
+ },
+ /* sprite_skull_debris_5 */
+ {
+ asset_id_enemy,
+ { 44, 10, 3, 6 }
+ },
+ /* sprite_enemy_bullet */
+ {
+ asset_id_bullet,
+ { 18, 0, 5, 5 }
}
};
diff --git a/sprite.h b/sprite.h
index a520b99..cf9d6e8 100644
--- a/sprite.h
+++ b/sprite.h
@@ -9,7 +9,15 @@ typedef enum {
sprite_player_bullet_left = 0,
sprite_player_bullet_right,
sprite_player_bullet_up,
- sprite_player_bullet_down
+ sprite_player_bullet_down,
+ sprite_skull_left,
+ sprite_skull_right,
+ sprite_skull_debris_1,
+ sprite_skull_debris_2,
+ sprite_skull_debris_3,
+ sprite_skull_debris_4,
+ sprite_skull_debris_5,
+ sprite_enemy_bullet
} Sprite_ID;
typedef struct {
diff --git a/standard.c b/standard.c
index 5e464f6..9a87342 100644
--- a/standard.c
+++ b/standard.c
@@ -135,6 +135,20 @@ int flerp(int a, int b, int t) {
return a + ((t * (b - a)) >> fbits);
}
+void vec_minise(int* x, int* y) {
+ if (
+ absolute(*x) <= fscale_lower_limit ||
+ absolute(*y) <= fscale_lower_limit) {
+ *x *= fscale_factor;
+ *y *= fscale_factor;
+ } else if (
+ absolute(*x) > fscale_upper_limit ||
+ absolute(*y) > fscale_upper_limit) {
+ *x /= fscale_factor;
+ *y /= fscale_factor;
+ }
+}
+
void vec_nrmise(int* x, int* y) {
int l;
diff --git a/standard.h b/standard.h
index 6f56ebc..88918af 100644
--- a/standard.h
+++ b/standard.h
@@ -4,6 +4,9 @@
int string_equal(const char* a, const char* b);
#define fbits 9
+#define fscale_lower_limit 16
+#define fscale_upper_limit 900
+#define fscale_factor 16
#define mini(a_, b_) ((a_) < (b_) ? (a_) : (b_))
#define maxi(a_, b_) ((a_) > (b_) ? (a_) : (b_))
@@ -15,6 +18,7 @@ int ftan(int t);
int flerp(int a, int b, int t);
int fsqrt(int v);
+void vec_minise(int* x, int* y);
void vec_nrmise(int* x, int* y);
void seed_rng(unsigned seed);
diff --git a/systems.h b/systems.h
index 0e405dd..0cc55ec 100644
--- a/systems.h
+++ b/systems.h
@@ -6,5 +6,7 @@
void animation_system(World* world);
void bullet_system(World* world);
void sprite_system(const World* world);
+void enemy_system(World* world);
+
#endif
diff --git a/world.h b/world.h
index d9995ab..9709337 100644
--- a/world.h
+++ b/world.h
@@ -13,13 +13,14 @@ struct World {
int entity_count;
int recycle_bin_count;
- unsigned char bitmask[max_entities];
+ unsigned short bitmask[max_entities];
Entity recycle_bin[max_entities];
CSprite sprites [max_entities];
CPosition positions [max_entities];
CAnimated animateds [max_entities];
CBullet bullets [max_entities];
+ CEnemy enemies [max_entities];
Player player;
};