From a72420a85fdfe85d6a6e67b8c70ed11537d532bd Mon Sep 17 00:00:00 2001 From: quou Date: Sat, 6 May 2023 20:30:58 +1000 Subject: Work on visual effects; Debris and player bullet impact effects. --- Makefile | 1 + animation.c | 14 +++++++ animation.h | 3 +- collision_system.c | 7 +++- components.h | 3 ++ debris.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ debris.h | 17 +++++++++ enemy.c | 44 ++++++++++++++++++++++ fx.c | 23 ++++++++++-- fx.h | 6 +++ game.c | 3 +- intermediate/bullet.bmp | Bin 6026 -> 19938 bytes map.c | 10 +++-- map.h | 1 + systems.h | 1 + world.h | 1 + 16 files changed, 221 insertions(+), 9 deletions(-) create mode 100644 debris.c create mode 100644 debris.h diff --git a/Makefile b/Makefile index 09bffef..44b9fa3 100644 --- a/Makefile +++ b/Makefile @@ -90,6 +90,7 @@ sources = \ asset.c \ bullet.c \ collision_system.c \ + debris.c \ enemy.c \ fx.c \ game.c \ diff --git a/animation.c b/animation.c index 6cf2584..a0fea2c 100644 --- a/animation.c +++ b/animation.c @@ -52,6 +52,20 @@ static const Animation animations[] = { }, 3, 5 + }, + /* animation_player_bullet_explode */ + { + { + { 30, 15, 15, 15 }, + { 45, 15, 15, 15 }, + { 60, 15, 15, 15 }, + { 75, 15, 15, 15 }, + { 90, 15, 15, 15 }, + { 105, 15, 15, 15 }, + { 120, 15, 15, 15 }, + }, + 7, + 1 } }; diff --git a/animation.h b/animation.h index 65956a6..e132202 100644 --- a/animation.h +++ b/animation.h @@ -9,7 +9,8 @@ typedef enum { animation_player_walk_right, animation_player_idle_left, animation_player_idle_right, - animation_enemy_bullet_explode + animation_enemy_bullet_explode, + animation_player_bullet_explode } Animation_ID; typedef struct { diff --git a/collision_system.c b/collision_system.c index 2a1ac03..cf1378c 100644 --- a/collision_system.c +++ b/collision_system.c @@ -58,10 +58,13 @@ static void handle_bullet_vs_enemy( Entity enemy ) { CEnemy* e; + const CPosition* pos; + pos = &world->positions[bullet]; e = &world->enemies[enemy]; e->hp--; destroy_entity(world, bullet); + new_player_bullet_explosion(world, pos->x, pos->y); } static void handle_bullet_vs_solid( @@ -73,10 +76,12 @@ static void handle_bullet_vs_solid( unsigned bbits; bbits = world->bitmask[bullet]; + pos = &world->positions[bullet]; if (bbits & ctype_enemy_bullet) { - pos = &world->positions[bullet]; new_enemy_bullet_explosion(world, pos->x, pos->y); + } else if (bbits & ctype_player_bullet) { + new_player_bullet_explosion(world, pos->x, pos->y); } destroy_entity(world, bullet); diff --git a/components.h b/components.h index 63a62c5..4c1b950 100644 --- a/components.h +++ b/components.h @@ -8,6 +8,9 @@ /* Components are POD. If you put a pointer in one of these, * you're a dumb poo poo head. */ +/* I should probably make a velocity component because it's + * duplicated a bit. Eh. */ + typedef struct { int x, y; } CPosition; diff --git a/debris.c b/debris.c new file mode 100644 index 0000000..cf4a526 --- /dev/null +++ b/debris.c @@ -0,0 +1,96 @@ +#include "components.h" +#include "map.h" +#include "sprite.h" +#include "standard.h" +#include "world.h" + +Entity new_debris( + struct World* world, + int x, + int y, + int vx, + int vy, + Sprite_ID spr +) { + Entity e; + CPosition* pos; + CDebris* debris; + CCollider* col; + CSprite* sprite; + + e = new_entity(world); + add_components( + world, + e, + ctype_moveable | + ctype_collider | + ctype_debris | + ctype_position | + ctype_sprite + ); + + pos = &world->positions[e]; + debris = &world->debris[e]; + col = &world->colliders[e]; + sprite = &world->sprites[e]; + + init_csprite(sprite, spr); + pos->x = x; + pos->y = y; + debris->vx = vx; + debris->vy = vy; + col->x = 0; + col->y = 0; + col->w = sprite->rect.w; + col->h = sprite->rect.h; + + return e; +} + +void debris_system(World* world) { + int i; + unsigned bits; + CPosition* pos; + CDebris* debris; + CSprite* sprite; + Bitmap map_bitmap; + const Bitmap* bmp; + + get_map_bitmap(&world->map, &map_bitmap); + + for (i = 0; i < world->entity_count; i++) { + bits = world->bitmask[i]; + if ( + (bits & ctype_debris) && + (bits & ctype_position) && + (bits & ctype_sprite) + ) { + pos = &world->positions[i]; + debris = &world->debris[i]; + sprite = &world->sprites[i]; + + pos->x += debris->vx; + pos->y += debris->vy; + debris->vx = (debris->vx << fbits) / 600; + debris->vy = (debris->vy << fbits) / 600; + + if (debris->vx == 0 && debris->vy == 0) { + /* Blit the motherfucker straight to the map + * so that we don't have to keep updating it + * when it's just sitting still. We can have + * INFINITE debris now. */ + + bmp = get_bitmap(sprite->id); + blit( + &map_bitmap, + bmp, + pos->x >> fbits, + pos->y >> fbits, + &sprite->rect + ); + + destroy_entity(world, i); + } + } + } +} diff --git a/debris.h b/debris.h new file mode 100644 index 0000000..d88a5ce --- /dev/null +++ b/debris.h @@ -0,0 +1,17 @@ +#ifndef debris_h +#define debris_h + +#include "sprite.h" + +struct World; + +int new_debris( + struct World* world, + int x, + int y, + int vx, + int vy, + Sprite_ID sprite +); + +#endif diff --git a/enemy.c b/enemy.c index 8b2642f..332a769 100644 --- a/enemy.c +++ b/enemy.c @@ -1,5 +1,6 @@ #include "bullet.h" #include "components.h" +#include "debris.h" #include "game_config.h" #include "sprite.h" #include "standard.h" @@ -44,6 +45,44 @@ Entity new_skull(World* world, int x, int y) { return e; } +static void new_skull_debris(World* world, int x, int y) { + new_debris( + world, + x, + y, + -2 << fbits, -2 << fbits, + sprite_skull_debris_1 + ); + new_debris( + world, + x, + y, + 0, -2 << fbits, + sprite_skull_debris_2 + ); + new_debris( + world, + x, + y, + -2 << fbits, 0, + sprite_skull_debris_3 + ); + new_debris( + world, + x, + y, + 0, 2 << fbits, + sprite_skull_debris_4 + ); + new_debris( + world, + x, + y, + 2 << fbits, 2 << fbits, + sprite_skull_debris_5 + ); +} + void enemy_system(World* world) { /* Skulls. */ int i; @@ -63,6 +102,11 @@ void enemy_system(World* world) { enemy = &world->enemies[i]; if (enemy->hp <= 0) { destroy_entity(world, i); + + if ((bits & ctype_position) && (bits & ctype_skull)) { + pos = &world->positions[i]; + new_skull_debris(world, pos->x, pos->y); + } } } } diff --git a/fx.c b/fx.c index f2a5f54..53670b4 100644 --- a/fx.c +++ b/fx.c @@ -2,10 +2,11 @@ #include "fx.h" #include "world.h" -int new_enemy_bullet_explosion( +static int new_fx( World* world, int x, - int y + int y, + Animation_ID anim ) { Entity e; CPosition* pos; @@ -32,9 +33,25 @@ int new_enemy_bullet_explosion( sprite->id = asset_id_bullet; sprite->rect = make_rect(0, 0, 16, 16); - animated->id = animation_enemy_bullet_explode; + animated->id = anim; animated->frame = 0; animated->timer = 0; return e; } + +int new_enemy_bullet_explosion( + World* world, + int x, + int y +) { + return new_fx(world, x, y, animation_enemy_bullet_explode); +} + +int new_player_bullet_explosion( + World* world, + int x, + int y +) { + return new_fx(world, x, y, animation_player_bullet_explode); +} diff --git a/fx.h b/fx.h index acbde30..dff8c47 100644 --- a/fx.h +++ b/fx.h @@ -11,4 +11,10 @@ int new_enemy_bullet_explosion( int y ); +int new_player_bullet_explosion( + struct World* world, + int x, + int y +); + #endif diff --git a/game.c b/game.c index 7eebb8b..f5edb8a 100644 --- a/game.c +++ b/game.c @@ -176,11 +176,12 @@ static void gameplay_update(Game* game) { update_player(player, world); enemy_system(world); + debris_system(world); bullet_system(world); collision_system(world); animation_system(world); - render_map(&world->map, cx, cy); update_camera(player, world); + render_map(&world->map, cx, cy); sprite_system(world); render_hud(game); diff --git a/intermediate/bullet.bmp b/intermediate/bullet.bmp index e92d3fb..4860a8b 100644 Binary files a/intermediate/bullet.bmp and b/intermediate/bullet.bmp differ diff --git a/map.c b/map.c index b9eb0ac..0cd6532 100644 --- a/map.c +++ b/map.c @@ -126,12 +126,16 @@ void render_map(Map* map, int cx, int cy) { Bitmap bitmap; Rectangle rect; - bitmap.pixels = map->pixels; - bitmap.w = mbmp_w; - bitmap.h = mbmp_h; + get_map_bitmap(map, &bitmap); rect.x = 0; rect.y = 0; rect.w = bitmap.w; rect.h = bitmap.h; render_bitmap(&bitmap, -cx >> fbits, -cy >> fbits, &rect); } + +void get_map_bitmap(Map* map, Bitmap* bitmap) { + bitmap->pixels = map->pixels; + bitmap->w = mbmp_w; + bitmap->h = mbmp_h; +} diff --git a/map.h b/map.h index 5b79195..79f5587 100644 --- a/map.h +++ b/map.h @@ -17,5 +17,6 @@ typedef struct { void init_map(Map* map, struct World* world); void render_map(Map* map, int cx, int cy); +void get_map_bitmap(Map* map, Bitmap* bitmap); #endif diff --git a/systems.h b/systems.h index 6bf4edc..672e704 100644 --- a/systems.h +++ b/systems.h @@ -8,5 +8,6 @@ void bullet_system(World* world); void collision_system(World* world); void enemy_system(World* world); void sprite_system(const World* world); +void debris_system(World* world); #endif diff --git a/world.h b/world.h index 8494509..5f324a8 100644 --- a/world.h +++ b/world.h @@ -23,6 +23,7 @@ struct World { CBullet bullets [max_entities]; CEnemy enemies [max_entities]; CCollider colliders [max_entities]; + CDebris debris [max_entities]; Player player; Map map; -- cgit v1.2.3-54-g00ecf