Have a basic understanding of what to do for the boss fight arena, but now want to start over fresh.

This commit is contained in:
Zed A. Shaw 2025-09-22 13:43:36 -04:00
parent e523aa8b02
commit 07e281d987
14 changed files with 76 additions and 217 deletions

View file

@ -1,156 +0,0 @@
#include "gui/boss_fight_ui.hpp"
#include "easings.hpp"
#include "sound.hpp"
#include <fmt/xchar.h>
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]"
"[=status_3|=status_4]"
"[=status_5|=status_6]"
"[=status_7|=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.frame_width = $sprite_config.width;
$boss_image = textures::get_sprite($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_sprite(boss.background);
$boss_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
$status.set<Background>($status.MAIN, {$status.$parser});
if(boss.stage) {
$boss_has_stage = true;
$boss_stage = textures::get_sprite(*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){
dbc::log(fmt::format("STATUS: {}", name));
}
});
if(name == "main_status") {
$status.set<Text>(button, {fmt::format(L"HP: {}", $combat.hp)});
} else {
$status.set<Text>(button, {L"Attack"});
}
}
$status.init();
for(auto& [name, cell] : $overlay.cells()) {
auto region = $overlay.entity(name);
$overlay.set<Clickable>(region, {
[this, name](auto){
dbc::log(fmt::format("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_text("overlay_1", L"YOU WON!");
$overlay.show_text("overlay_4", L"CLICK TO CONTINUE...");
}
$status.render(window);
$overlay.render(window);
}
bool BossFightUI::mouse(float x, float y, guecs::Modifiers mods) {
if($status.mouse(x, y, mods)) {
dbc::log("STATUS button pressed");
}
if($overlay.mouse(x, y, mods)) {
$animation.play();
sound::play("Sword_Hit_1");
$boss_hit = !$boss_hit;
$combat.hp--;
}
return false;
}
}

View file

@ -1,48 +0,0 @@
#pragma once
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Font.hpp>
#include <guecs/ui.hpp>
#include "textures.hpp"
#include "components.hpp"
#include <SFML/System/Clock.hpp>
// aspect ratio of art is 3/2 so 1.5
// possible sizes: 900/600; 1620/1080; 1800/1200
// To calculate it do short side * 1.5 so 1080 * 1.5 == 1620
//
// Side panel = 300/1080
namespace gui {
using std::string;
class BossFightUI {
public:
sf::Clock $clock;
bool $boss_hit = false;
sf::Vector2f $boss_pos;
components::Combat $combat;
components::Sprite $sprite_config;
components::Sound $sounds;
components::Animation $animation;
guecs::UI $status;
guecs::UI $overlay;
textures::SpriteTexture $boss_image;
textures::SpriteTexture $boss_background;
bool $boss_has_stage = false;
textures::SpriteTexture $boss_stage;
std::shared_ptr<DinkyECS::World> $world = nullptr;
DinkyECS::Entity $boss_id;
components::GameConfig& $config;
BossFightUI(std::shared_ptr<DinkyECS::World> world, DinkyECS::Entity boss_id);
void init();
void render(sf::RenderWindow& window);
bool mouse(float x, float y, guecs::Modifiers mods);
void bounce_boss(sf::RenderWindow& window);
bool boss_dead() { return $combat.hp < 0; }
void configure_sprite();
void configure_background();
void configure_gui();
};
}

View file

@ -7,7 +7,7 @@
#include "gui/combat_ui.hpp"
#include "gui/status_ui.hpp"
#include "gui/loot_ui.hpp"
#include "gui/boss_fight_ui.hpp"
#include "boss/ui.hpp"
#include "gui/map_view.hpp"
#include "events.hpp"
#include "gui/event_router.hpp"
@ -36,7 +36,7 @@ namespace gui {
int $temp_attack_id = 0;
DebugUI $debug_ui;
MainUI $main_ui;
std::shared_ptr<BossFightUI> $boss_fight_ui = nullptr;
std::shared_ptr<boss::UI> $boss_fight_ui = nullptr;
CombatUI $combat_ui;
StatusUI $status_ui;
MapViewUI $map_ui;