diff options
author | quou <quou@disroot.org> | 2023-05-05 09:25:39 +1000 |
---|---|---|
committer | quou <quou@disroot.org> | 2023-05-05 09:25:39 +1000 |
commit | 280552fa4750b5dac9243782f9c0a7e0b7eea6f8 (patch) | |
tree | 6385dc740cc965dad7dc628e8b10738724ec0a42 | |
parent | 0a083f5a9a747083bbc3a1f0689e76ac5fc3a3b9 (diff) |
Add a basic enemy.
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | asset.c | 3 | ||||
-rw-r--r-- | asset.h | 3 | ||||
-rw-r--r-- | bullet.c | 37 | ||||
-rw-r--r-- | bullet.h | 8 | ||||
-rw-r--r-- | components.h | 15 | ||||
-rw-r--r-- | enemy.c | 103 | ||||
-rw-r--r-- | enemy.h | 8 | ||||
-rw-r--r-- | game_config.h | 6 | ||||
-rw-r--r-- | intermediate/enemy.bmp | bin | 0 -> 8330 bytes | |||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | player.c | 4 | ||||
-rw-r--r-- | sprite.c | 40 | ||||
-rw-r--r-- | sprite.h | 10 | ||||
-rw-r--r-- | standard.c | 14 | ||||
-rw-r--r-- | standard.h | 4 | ||||
-rw-r--r-- | systems.h | 2 | ||||
-rw-r--r-- | world.h | 3 |
18 files changed, 258 insertions, 7 deletions
@@ -89,6 +89,7 @@ sources = \ animation_system.c \ asset.c \ bullet.c \ + enemy.c \ main.c \ malware.c \ platform.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 { @@ -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; @@ -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; @@ -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 @@ -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++; + } + } +} @@ -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 Binary files differnew file mode 100644 index 0000000..da1e068 --- /dev/null +++ b/intermediate/enemy.bmp @@ -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); @@ -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); @@ -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 } } }; @@ -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 { @@ -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; @@ -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); @@ -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 @@ -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; }; |