diff --git a/assets/bosses.json b/assets/bosses.json new file mode 100644 index 0000000..bc419d3 --- /dev/null +++ b/assets/bosses.json @@ -0,0 +1,14 @@ +{ + "RAT_KING": { + "background": "boss_fight_background", + "weapon_sound": "Sword_Hit_2", + "components": [ + {"_type": "Combat", "hp": 50, "max_hp": 50, "damage": 50, "dead": false}, + {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, + {"_type": "EnemyConfig", "hearing_distance": 3}, + {"_type": "Animation", "easing": 2, "ease_rate": 0.2, "scale": 0.2, "simple": false, "frames": 2, "speed": 0.02}, + {"_type": "Sprite", "name": "rat_king_boss", "width": 720, "height": 720}, + {"_type": "Sound", "attack": "Marmot_Scream_1", "death": "Creature_Death_1"} + ] + } +} diff --git a/assets/config.json b/assets/config.json index ea0fd89..a2a7c8d 100644 --- a/assets/config.json +++ b/assets/config.json @@ -48,11 +48,6 @@ "down_the_well": "assets/down_the_well.jpg", "boss_fight_background": "assets/rat_king_boss_fight_background.jpg" }, - "enemy": { - "HEARING_DISTANCE": 5 - }, - "player": { - }, "worldgen": { "enemy_probability": 80, "empty_room_probability": 10, diff --git a/assets/devices.json b/assets/devices.json index ad5eab3..f5033ee 100644 --- a/assets/devices.json +++ b/assets/devices.json @@ -14,7 +14,7 @@ {"_type": "Device", "config": {"test": true}, "events": ["Events::GUI::STAIRS_DOWN"]}, - {"_type": "Sprite", "name": "well_down"} + {"_type": "Sprite", "name": "well_down", "width": 256, "height": 256} ] }, "STAIRS_UP": { @@ -31,7 +31,7 @@ {"_type": "Device", "config": {"test": true}, "events": ["Events::GUI::STAIRS_UP"]}, - {"_type": "Sprite", "name": "rope_vines_up"} + {"_type": "Sprite", "name": "rope_vines_up", "width": 256, "height": 256} ] }, "TRIPWIRE_TRAP": { @@ -47,7 +47,7 @@ {"_type": "Device", "config": {"test": true}, "events": ["Events::GUI::TRAP"]}, - {"_type": "Sprite", "name": "tripwire_trap"} + {"_type": "Sprite", "name": "tripwire_trap", "width": 256, "height": 256} ] } } diff --git a/assets/enemies.json b/assets/enemies.json index 9649323..f639fd9 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -21,7 +21,7 @@ {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "hearing_distance": 5}, {"_type": "Animation", "easing": 1, "ease_rate": 0.2, "scale": 0.1, "simple": true, "frames": 10, "speed": 0.3}, - {"_type": "Sprite", "name": "armored_knight"}, + {"_type": "Sprite", "name": "armored_knight", "width": 256, "height": 256, "width": 256, "height": 256}, {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Humanoid_Death_1"} ] }, @@ -34,7 +34,7 @@ {"_type": "Combat", "hp": 40, "max_hp": 40, "damage": 10, "dead": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": true}, {"_type": "EnemyConfig", "hearing_distance": 5}, - {"_type": "Sprite", "name": "axe_ranger"}, + {"_type": "Sprite", "name": "axe_ranger", "width": 256, "height": 256}, {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": false, "frames": 2, "speed": 0.6}, {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Ranger_1"} ] @@ -48,8 +48,8 @@ {"_type": "Combat", "hp": 50, "max_hp": 50, "damage": 50, "dead": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "hearing_distance": 5}, - {"_type": "Sprite", "name": "evil_eye"}, - {"_type": "Animation", "easing": 3, "ease_rate": 0.1, "scale": 0.1, "simple": false, "frames": 2, "speed": 0.3}, + {"_type": "Sprite", "name": "evil_eye", "width": 256, "height": 256}, + {"_type": "Animation", "easing": 3, "ease_rate": 0.1, "scale": 0.1, "simple": false, "frames": 2, "speed": 0.1}, {"_type": "Sound", "attack": "Evil_Eye_Sound_2", "death": "Evil_Eye_Sound_1"} ] }, @@ -63,25 +63,10 @@ {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "hearing_distance": 10}, {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0}, - {"_type": "Sprite", "name": "rat_with_sword"}, + {"_type": "Sprite", "name": "rat_with_sword", "width": 256, "height": 256}, {"_type": "Sound", "attack": "Small_Rat", "death": "Creature_Death_1"} ] }, - "RAT_KING": { - "placement": "fixed", - "components": [ - {"_type": "Tile", "display": "\u08ac", - "foreground": [205, 164, 100], - "background": [30, 20, 75] - }, - {"_type": "Combat", "hp": 50, "max_hp": 50, "damage": 50, "dead": false}, - {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, - {"_type": "EnemyConfig", "hearing_distance": 3}, - {"_type": "Animation", "easing": 2, "ease_rate": 0.2, "scale": 0.2, "simple": false, "frames": 2, "speed": 0.02}, - {"_type": "Sprite", "name": "rat_king_boss"}, - {"_type": "Sound", "attack": "Marmot_Scream_1", "death": "Creature_Death_1"} - ] - }, "SPIDER_GIANT_HAIRY": { "components": [ {"_type": "Tile", "display": "\u08ea", @@ -92,7 +77,7 @@ {"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "EnemyConfig", "hearing_distance": 10}, {"_type": "Animation", "easing": 2, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0}, - {"_type": "Sprite", "name": "hairy_spider"}, + {"_type": "Sprite", "name": "hairy_spider", "width": 256, "height": 256}, {"_type": "Sound", "attack": "Spider_1", "death": "Spider_2"} ] } diff --git a/assets/items.json b/assets/items.json index 599b39f..f41c140 100644 --- a/assets/items.json +++ b/assets/items.json @@ -10,7 +10,7 @@ "foreground": [24, 120, 189], "background": [230,120, 120] }, - {"_type": "Sprite", "name": "torch_horizontal_floor"}, + {"_type": "Sprite", "name": "torch_horizontal_floor", "width": 256, "height": 256}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ] }, @@ -25,7 +25,7 @@ "foreground": [24, 120, 189], "background": [24, 120, 189] }, - {"_type": "Sprite", "name": "cinqueda"}, + {"_type": "Sprite", "name": "cinqueda", "width": 256, "height": 256}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ] }, @@ -39,7 +39,7 @@ "background": [150, 100, 189] }, {"_type": "Loot", "amount": 10}, - {"_type": "Sprite", "name": "barrel_small"}, + {"_type": "Sprite", "name": "barrel_small", "width": 256, "height": 256}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ], "inventory_count": 1 @@ -55,7 +55,7 @@ "background": [24, 205, 210] }, {"_type": "LightSource", "strength": 50, "radius": 2.8}, - {"_type": "Sprite", "name": "torch_pillar"}, + {"_type": "Sprite", "name": "torch_pillar", "width": 256, "height": 256}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ] }, @@ -70,7 +70,7 @@ "background": [255, 205, 189] }, {"_type": "Curative", "hp": 20}, - {"_type": "Sprite", "name": "healing_potion_small"}, + {"_type": "Sprite", "name": "healing_potion_small", "width": 256, "height": 256}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ] }, @@ -85,7 +85,7 @@ "background": [24, 205, 189] }, {"_type": "Loot", "amount": 10}, - {"_type": "Sprite", "name": "grave_stone"}, + {"_type": "Sprite", "name": "grave_stone", "width": 256, "height": 256}, {"_type": "Sound", "attack": "pickup", "death": "blank"} ] } diff --git a/boss_fight_ui.cpp b/boss_fight_ui.cpp index 5b9057d..26e3fe9 100644 --- a/boss_fight_ui.cpp +++ b/boss_fight_ui.cpp @@ -3,45 +3,56 @@ #include "sound.hpp" namespace gui { - BossFightUI::BossFightUI(GameLevel level) - : $level(level) + BossFightUI::BossFightUI(GameLevel level, std::string boss_name) + : $level(level), + $config($level.world->get_the()), + $boss_name(boss_name) { - $status.position(0, 0, 300, SCREEN_HEIGHT); + $status.position(0, 0, BOSS_VIEW_X, SCREEN_HEIGHT); $status.layout( "[main_status]" "[(150)status_3|(150)status_4]" "[(150)status_5|(150)status_6]" - "[(150)status_7|(150)status_8]" - ); + "[(150)status_7|(150)status_8]"); + + $overlay.position(BOSS_VIEW_X, BOSS_VIEW_Y, + BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT); - $overlay.position(300, 0, SCREEN_WIDTH - 300, SCREEN_HEIGHT); $overlay.layout("[overlay_1|overlay_2|overlay_4]" - "[overlay_5|overlay_6|overlay_8]" - "[overlay_9|overlay_10|overlay_12]" - "[overlay_13|overlay_14|overlay_16]"); + "[overlay_5|overlay_6|overlay_8]" + "[overlay_9|overlay_10|overlay_12]" + "[overlay_13|overlay_14|overlay_16]"); - $boss_background = textures::get("boss_fight_background"); - auto bg_bounds = $boss_background.sprite->getLocalBounds(); - $boss_background.sprite->setPosition({300, 0}); + $sounds = components::get($config.bosses[boss_name]); + $weapon_hit_sound = $config.bosses[$boss_name]["weapon_sound"]; + } - $boss_image = textures::get("rat_king_boss"); - sf::IntRect frame_rect{{0,0},{720,720}}; + void BossFightUI::configure_sprite() { + auto& boss = $config.bosses[$boss_name]; + $sprite_config = components::get(boss); + $animation = components::get(boss); + $animation.texture_width = $sprite_config.width; + + $boss_image = textures::get($sprite_config.name); + sf::IntRect frame_rect{{0,0},{$sprite_config.width,$sprite_config.height}}; $boss_image.sprite->setTextureRect(frame_rect); $boss_image.sprite->setScale($scale); + auto bounds = $boss_image.sprite->getLocalBounds(); + auto bg_bounds = $boss_background.sprite->getLocalBounds(); float x_diff = bg_bounds.size.x / 2; $boss_image.sprite->setOrigin({bounds.size.x / 2, bounds.size.y / 2}); - $boss_image.sprite->setPosition({300.0f + x_diff, bounds.size.y / 2}); + $boss_image.sprite->setPosition({float(BOSS_VIEW_X) + x_diff, bounds.size.y / 2}); } - void BossFightUI::init() { - auto& config = $level.world->get_the(); - $sounds = components::get(config.enemies["RAT_KING"]); - $animation = components::get(config.enemies["RAT_KING"]); - $animation.texture_width = 720; - + void BossFightUI::configure_background() { + auto& boss = $config.bosses[$boss_name]; + $boss_background = textures::get(boss["background"]); + $boss_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); $status.world().set_the({$status.$parser}); + } + void BossFightUI::configure_gui() { for(auto& [name, cell] : $status.cells()) { auto button = $status.entity(name); $status.set(button, {}); @@ -66,8 +77,15 @@ namespace gui { $overlay.init(); } + void BossFightUI::init() { + // background must come first + configure_background(); + configure_sprite(); + configure_gui(); + } + void BossFightUI::bounce_boss(sf::RenderWindow& window) { - sf::IntRect frame_rect{{0,0},{720,720}}; + sf::IntRect frame_rect{{0,0},{$sprite_config.width,$sprite_config.height}}; auto scale = $scale; $animation.step(scale, frame_rect); $boss_image.sprite->setScale(scale); @@ -76,8 +94,8 @@ namespace gui { sound::play($sounds.attack); } - if(!sound::playing("Sword_Hit_2") && $animation.subframe > 1.2 && $animation.subframe < 1.5) { - sound::play("Sword_Hit_2"); + if(!sound::playing($weapon_hit_sound) && $animation.subframe > 1.2 && $animation.subframe < 1.5) { + sound::play($weapon_hit_sound); } $boss_image.sprite->setTextureRect(frame_rect); diff --git a/boss_fight_ui.hpp b/boss_fight_ui.hpp index 6e6f4a4..81b8981 100644 --- a/boss_fight_ui.hpp +++ b/boss_fight_ui.hpp @@ -4,6 +4,7 @@ #include #include "guecs.hpp" #include "textures.hpp" +#include "components.hpp" #include // aspect ratio of art is 3/2 so 1.5 @@ -22,15 +23,19 @@ namespace gui { int $boss_hp = 10; bool $boss_hit = false; sf::Vector2f $scale{0.8, 0.8}; + std::string $weapon_hit_sound; + components::Sprite $sprite_config; components::Sound $sounds; components::Animation $animation; GameLevel $level; + components::GameConfig& $config; + std::string $boss_name; guecs::UI $status; guecs::UI $overlay; textures::SpriteTexture $boss_image; textures::SpriteTexture $boss_background; - BossFightUI(GameLevel level); + BossFightUI(GameLevel level, std::string boss_name); void init(); void render(sf::RenderWindow& window); @@ -38,5 +43,8 @@ namespace gui { void bounce_boss(sf::RenderWindow& window); bool boss_dead() { return $boss_hp < 0; } void update_level(GameLevel& level); + void configure_sprite(); + void configure_background(); + void configure_gui(); }; } diff --git a/components.hpp b/components.hpp index a240ff8..7f1fe04 100644 --- a/components.hpp +++ b/components.hpp @@ -46,6 +46,7 @@ namespace components { Config items; Config tiles; Config devices; + Config bosses; }; struct EnemyConfig { @@ -91,6 +92,8 @@ namespace components { struct Sprite { string name; + int width; + int height; }; struct Sound { @@ -118,7 +121,7 @@ namespace components { template struct NameOf; ENROLL_COMPONENT(Tile, display, foreground, background); - ENROLL_COMPONENT(Sprite, name); + ENROLL_COMPONENT(Sprite, name, width, height); ENROLL_COMPONENT(Curative, hp); ENROLL_COMPONENT(LightSource, strength, radius); ENROLL_COMPONENT(Weapon, damage); diff --git a/constants.hpp b/constants.hpp index 2bd01fa..5a7d1c4 100644 --- a/constants.hpp +++ b/constants.hpp @@ -11,6 +11,12 @@ constexpr const int SCREEN_WIDTH=1280; constexpr const int SCREEN_HEIGHT=720; constexpr const int RAY_VIEW_X=(SCREEN_WIDTH - RAY_VIEW_WIDTH); constexpr const int RAY_VIEW_Y=0; + +constexpr const int BOSS_VIEW_WIDTH=1080; +constexpr const int BOSS_VIEW_HEIGHT=SCREEN_HEIGHT; +constexpr const int BOSS_VIEW_X=SCREEN_WIDTH - BOSS_VIEW_WIDTH; +constexpr const int BOSS_VIEW_Y=0; + constexpr const bool VSYNC=false; constexpr const int FRAME_LIMIT=60; constexpr const int NUM_SPRITES=1; diff --git a/gui_fsm.cpp b/gui_fsm.cpp index 47b1ad2..60e6653 100644 --- a/gui_fsm.cpp +++ b/gui_fsm.cpp @@ -20,7 +20,7 @@ namespace gui { $map_ui($level), $combat_ui($level), $status_ui($level), - $boss_fight_ui($level), + $boss_fight_ui($level, "RAT_KING"), $font{FONT_FILE_NAME} { } diff --git a/main.cpp b/main.cpp index d5aa686..89c047a 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,7 @@ int main(int argc, char* argv[]) { textures::init(); sound::init(); - sound::mute(false); + sound::mute(true); gui::FSM main; main.event(gui::Event::STARTED); Autowalker walker(main); diff --git a/save.cpp b/save.cpp index 43ef935..5489a2e 100644 --- a/save.cpp +++ b/save.cpp @@ -35,8 +35,9 @@ void save::load_configs(DinkyECS::World &world) { Config items("./assets/items.json"); Config tiles("./assets/tiles.json"); Config devices("./assets/devices.json"); + Config bosses("./assets/bosses.json"); world.set_the({ - game, enemies, items, tiles, devices + game, enemies, items, tiles, devices, bosses }); }