#include "boss_fight_ui.hpp" #include "easings.hpp" #include "sound.hpp" namespace gui { using namespace guecs; BossFightUI::BossFightUI(shared_ptr<DinkyECS::World> world, DinkyECS::Entity boss_id) : $world(world), $boss_id(boss_id), $config(world->get_the<components::GameConfig>()) { $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]"); $overlay.position(BOSS_VIEW_X, BOSS_VIEW_Y, BOSS_VIEW_WIDTH, BOSS_VIEW_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]"); $sounds = $world->get<components::Sound>($boss_id); $combat = $world->get<components::Combat>($boss_id); } void BossFightUI::configure_sprite() { $sprite_config = $world->get<components::Sprite>($boss_id); $animation = $world->get<components::Animation>($boss_id); $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({$sprite_config.scale, $sprite_config.scale}); auto bounds = $boss_image.sprite->getLocalBounds(); auto bg_bounds = $boss_background.sprite->getLocalBounds(); float x_diff = bg_bounds.size.x / 2; $boss_pos = {float(BOSS_VIEW_X) + x_diff, bounds.size.y / 2}; $boss_image.sprite->setOrigin({bounds.size.x / 2, bounds.size.y / 2}); $boss_image.sprite->setPosition($boss_pos); } void BossFightUI::configure_background() { auto& boss = $world->get<components::BossFight>($boss_id); $boss_background = textures::get(boss.background); $boss_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); $status.world().set_the<Background>({$status.$parser}); if(boss.stage) { $boss_has_stage = true; $boss_stage = textures::get(*boss.stage); $boss_stage.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y}); } } void BossFightUI::configure_gui() { for(auto& [name, cell] : $status.cells()) { auto button = $status.entity(name); $status.set<Rectangle>(button, {}); $status.set<Clickable>(button, { [this, name](auto, auto){ fmt::println("STATUS: {}", name); } }); if(name == "main_status") { $status.set<Textual>(button, {fmt::format("HP: {}", $combat.hp)}); } else { $status.set<Label>(button, {"Attack"}); } } $status.init(); for(auto& [name, cell] : $overlay.cells()) { auto region = $overlay.entity(name); $overlay.set<Clickable>(region, { [this, name](auto, auto){ fmt::println("OVERLAY: {}", name); } }); } $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},{$sprite_config.width,$sprite_config.height}}; sf::Vector2f scale{$sprite_config.scale, $sprite_config.scale}; sf::Vector2f pos{$boss_pos.x, $boss_pos.y}; $animation.step(scale, pos, frame_rect); $boss_image.sprite->setScale(scale); if($animation.stationary) $boss_image.sprite->setPosition(pos); if(!sound::playing($sounds.attack) && $animation.current == 1) { sound::play($sounds.attack); } $boss_image.sprite->setTextureRect(frame_rect); window.draw(*$boss_image.sprite); } void BossFightUI::render(sf::RenderWindow& window) { window.draw(*$boss_background.sprite); if($boss_hit) { bounce_boss(window); } else { window.draw(*$boss_image.sprite); } if($boss_has_stage) { window.draw(*$boss_stage.sprite); } if($combat.hp == 0) { $overlay.show_label("overlay_1", "YOU WON!"); $overlay.show_label("overlay_4", "CLICK TO CONTINUE..."); } $status.render(window); $overlay.render(window); } bool BossFightUI::mouse(float x, float y) { if($status.mouse(x, y)) { fmt::println("STATUS"); } if($overlay.mouse(x, y)) { $animation.play(); sound::play("Sword_Hit_1"); $boss_hit = !$boss_hit; $combat.hp--; } return false; } }