From 4f39f2a504e0e1581af22f66775167d2f7560098 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Thu, 23 Oct 2025 11:37:35 -0400 Subject: [PATCH] Moved the animated scene into its own system for better development. --- boss/fight.cpp | 2 +- boss/fight.hpp | 1 + boss/ui.cpp | 136 +++----------------------------------------- boss/ui.hpp | 34 ++--------- meson.build | 1 + scene.cpp | 150 +++++++++++++++++++++++++++++++++++++++++++++++++ scene.hpp | 44 +++++++++++++++ 7 files changed, 209 insertions(+), 159 deletions(-) create mode 100644 scene.cpp create mode 100644 scene.hpp diff --git a/boss/fight.cpp b/boss/fight.cpp index 0302ead..502fc18 100644 --- a/boss/fight.cpp +++ b/boss/fight.cpp @@ -6,7 +6,7 @@ namespace boss { Fight::Fight(shared_ptr world, Entity boss_id) : $world(world), $boss_id(boss_id), - $ui(world, boss_id) + $ui(world->get($boss_id), boss_id) { $ui.init(); } diff --git a/boss/fight.hpp b/boss/fight.hpp index 92ee4ca..9961b8c 100644 --- a/boss/fight.hpp +++ b/boss/fight.hpp @@ -8,6 +8,7 @@ #include namespace boss { + using namespace DinkyECS; using std::shared_ptr; enum class State { diff --git a/boss/ui.cpp b/boss/ui.cpp index 2a351ae..bc4cad0 100644 --- a/boss/ui.cpp +++ b/boss/ui.cpp @@ -1,99 +1,20 @@ #include "boss/ui.hpp" +#include "scene.hpp" #include "constants.hpp" -#include "components.hpp" -#include "animation.hpp" #include #include -#include "sound.hpp" - -const bool DEBUG=false; -const bool YOU_REMOVED_MID_CELL_IDIOT=false; namespace boss { using namespace guecs; - UI::UI(shared_ptr world, Entity boss_id) : - $world(world), + UI::UI(components::AnimatedScene& scene, Entity boss_id) : $boss_id(boss_id), - $scene(world->get($boss_id)), - $combat_ui(true) + $combat_ui(true), + $arena(scene) { - - for(auto& config : $scene.actors) { - std::string sprite_name = config["sprite"]; - auto st = textures::get_sprite(sprite_name); - float scale_x = config["scale_x"]; - float scale_y = config["scale_y"]; - - auto anim = animation::load(sprite_name); - anim.scale_x = scale_x; - anim.scale_y = scale_y; - - auto& cell = config["cell"]; - std::string key = config["name"]; - - dbc::check(!$actor_name_ids.contains(key), - fmt::format("actors key {} already exists", key)); - - $actors.emplace_back(st, anim, cell, scale_x, scale_y, 0, 0); - $actor_name_ids.try_emplace(key, $actors.size() - 1); - } - - // floor is std::optional - if($scene.floor) { - $floor_sprite = textures::get_sprite(*$scene.floor); - } - - for(auto& fixture : $scene.fixtures) { - std::string name = fixture["name"]; - auto st = textures::get_sprite(name); - // clone the sprite so it can be positioned - st.sprite = std::make_shared(*st.texture); - float scale_x = fixture["scale_x"]; - float scale_y = fixture["scale_y"]; - - auto anim = animation::load(name); - anim.scale_x = scale_x; - anim.scale_y = scale_y; - anim.play(); - - std::string cell = fixture["cell"]; - float x = fixture["x"]; - float y = fixture["y"]; - - $fixtures.emplace_back(st, anim, cell, scale_x, scale_y, x, y); - } } void UI::init() { - $arena.position(SCREEN_WIDTH-BOSS_VIEW_WIDTH,0, BOSS_VIEW_WIDTH, SCREEN_HEIGHT); - $arena.set($arena.MAIN, {$arena.$parser, THEME.TRANSPARENT}); - auto& background = $arena.get($arena.MAIN); - background.set_sprite($scene.background, true); - - $arena.layout( - "[status|boss1 |boss2 |boss3 |boss4 |_]" - "[torch1|boss5 |boss6 |boss7 |boss8 |torch2]" - "[floor1|boss9 |boss10|boss11|boss12|_]" - "[floor2|boss13|boss14|boss15|boss16|_]" - "[floor3|player1|player2|player3|player4|_]" - "[floor4|player5|player6|player7|player8|_]" - ); - - if($scene.floor) { - position_sprite($floor_sprite, $scene.floor_pos, 1.0f, 1.0f, false); - } - - for(auto& actor : $actors) { - actor.pos = position_sprite(actor.st, actor.cell, - actor.scale_x, actor.scale_y, false, actor.x, actor.y); - } - - for(auto& fixture : $fixtures) { - fixture.pos = position_sprite(fixture.st, fixture.cell, - fixture.scale_x, fixture.scale_y, false, fixture.x, fixture.y); - } - $arena.init(); $actions.position(0,0, SCREEN_WIDTH-BOSS_VIEW_WIDTH, SCREEN_HEIGHT); @@ -115,38 +36,10 @@ namespace boss { $combat_ui.init(cell.x, cell.y, cell.w, cell.h); } - sf::Vector2f UI::position_sprite(textures::SpriteTexture& st, const std::string& cell_name, float scale_x, float scale_y, bool at_mid, float x_diff, float y_diff) { - - auto& cell = $arena.cell_for(cell_name); - float x = float(at_mid ? cell.mid_x : cell.x); - float y = float(at_mid ? cell.mid_y : cell.y); - - sf::Vector2f pos{x + x_diff, y + y_diff}; - st.sprite->setPosition(pos); - st.sprite->setScale({scale_x, scale_y}); - - return pos; - } - void UI::render(sf::RenderWindow& window) { $actions.render(window); $combat_ui.render(window); - - if($floor_sprite.sprite) { - window.draw(*$floor_sprite.sprite); - } - $arena.render(window); - - for(auto& fixture : $fixtures) { - window.draw(*fixture.st.sprite); - } - - for(auto& actor : $actors) { - window.draw(*actor.st.sprite); - } - - if(DEBUG) $arena.debug_layout(window); } bool UI::mouse(float x, float y, Modifiers mods) { @@ -156,31 +49,18 @@ namespace boss { } void UI::status(const std::wstring& msg) { - $arena.show_text("status", msg); + $arena.$ui.show_text("status", msg); } void UI::move_actor(const std::string& actor, const std::string& cell_name) { - auto& config = $actors.at($actor_name_ids.at(actor)); - config.cell = cell_name; - config.pos = position_sprite(config.st, config.cell, config.scale_x, config.scale_y, YOU_REMOVED_MID_CELL_IDIOT); + $arena.move_actor(actor, cell_name); } void UI::animate_actor(const std::string& actor) { - auto& config = $actors.at($actor_name_ids.at(actor)); - config.anim.play(); + $arena.animate_actor(actor); } void UI::play_animations() { - for(auto& fixture : $fixtures) { - if(fixture.anim.playing) { - animation::apply(fixture.anim, *fixture.st.sprite, fixture.pos); - } - } - - for(auto& actor : $actors) { - if(actor.anim.playing) { - animation::apply(actor.anim, *actor.st.sprite, actor.pos); - } - } + $arena.play_animations(); } } diff --git a/boss/ui.hpp b/boss/ui.hpp index 2c33594..a1673db 100644 --- a/boss/ui.hpp +++ b/boss/ui.hpp @@ -1,49 +1,23 @@ #pragma once -#include "dinkyecs.hpp" #include -#include #include -#include "textures.hpp" #include "gui/combat_ui.hpp" -#include "components.hpp" -#include - -struct AnimatedFixture { - textures::SpriteTexture st; - components::Animation anim; - std::string cell; - float scale_x; - float scale_y; - float x; - float y; - bool at_mid=false; - sf::Vector2f pos{0,0}; -}; +#include "scene.hpp" namespace boss { using std::shared_ptr; - using namespace DinkyECS; - using namespace textures; struct UI { - shared_ptr $world = nullptr; - Entity $boss_id = NONE; - components::AnimatedScene $scene; + DinkyECS::Entity $boss_id = DinkyECS::NONE; gui::CombatUI $combat_ui; - SpriteTexture $floor_sprite; - guecs::UI $arena; + scene::Engine $arena; guecs::UI $actions; - std::unordered_map $actor_name_ids; - std::vector $fixtures; - std::vector $actors; - - UI(shared_ptr world, Entity boss_id); + UI(components::AnimatedScene &scene, DinkyECS::Entity boss_id); void init(); void render(sf::RenderWindow& window); bool mouse(float x, float y, guecs::Modifiers mods); - sf::Vector2f position_sprite(textures::SpriteTexture& st, const std::string& cell_name, float scale_x, float scale_y, bool at_mid, float x_diff=0.0f, float y_diff=0.0f); void status(const std::wstring& msg); void move_actor(const std::string& actor, const std::string& cell_name); void animate_actor(const std::string& actor); diff --git a/meson.build b/meson.build index c2c5d37..260c1ab 100644 --- a/meson.build +++ b/meson.build @@ -118,6 +118,7 @@ sources = [ 'rand.cpp', 'raycaster.cpp', 'rituals.cpp', + 'scene.cpp', 'shaders.cpp', 'shiterator.hpp', 'sound.cpp', diff --git a/scene.cpp b/scene.cpp new file mode 100644 index 0000000..98570fa --- /dev/null +++ b/scene.cpp @@ -0,0 +1,150 @@ +#include "scene.hpp" +#include "animation.hpp" + +const bool DEBUG=false; +const bool YOU_REMOVED_MID_CELL_IDIOT=false; + +namespace scene { + using namespace guecs; + + Engine::Engine(components::AnimatedScene& scene) : + $scene(scene) + { + for(auto& config : $scene.actors) { + std::string sprite_name = config["sprite"]; + auto st = textures::get_sprite(sprite_name); + float scale_x = config["scale_x"]; + float scale_y = config["scale_y"]; + + auto anim = animation::load(sprite_name); + anim.scale_x = scale_x; + anim.scale_y = scale_y; + + auto& cell = config["cell"]; + std::string key = config["name"]; + + dbc::check(!$actor_name_ids.contains(key), + fmt::format("actors key {} already exists", key)); + + $actors.emplace_back(st, anim, cell, scale_x, scale_y, 0, 0); + $actor_name_ids.try_emplace(key, $actors.size() - 1); + } + + // floor is std::optional + if($scene.floor) { + $floor_sprite = textures::get_sprite(*$scene.floor); + } + + for(auto& fixture : $scene.fixtures) { + std::string name = fixture["name"]; + auto st = textures::get_sprite(name); + // clone the sprite so it can be positioned + st.sprite = std::make_shared(*st.texture); + float scale_x = fixture["scale_x"]; + float scale_y = fixture["scale_y"]; + + auto anim = animation::load(name); + anim.scale_x = scale_x; + anim.scale_y = scale_y; + anim.play(); + + std::string cell = fixture["cell"]; + float x = fixture["x"]; + float y = fixture["y"]; + + $fixtures.emplace_back(st, anim, cell, scale_x, scale_y, x, y); + } + } + + void Engine::init() { + $ui.position(SCREEN_WIDTH-BOSS_VIEW_WIDTH,0, BOSS_VIEW_WIDTH, SCREEN_HEIGHT); + $ui.set($ui.MAIN, {$ui.$parser, THEME.TRANSPARENT}); + auto& background = $ui.get($ui.MAIN); + background.set_sprite($scene.background, true); + + $ui.layout( + "[status|boss1 |boss2 |boss3 |boss4 |_]" + "[torch1|boss5 |boss6 |boss7 |boss8 |torch2]" + "[floor1|boss9 |boss10|boss11|boss12|_]" + "[floor2|boss13|boss14|boss15|boss16|_]" + "[floor3|player1|player2|player3|player4|_]" + "[floor4|player5|player6|player7|player8|_]" + ); + + if($scene.floor) { + position_sprite($floor_sprite, $scene.floor_pos, 1.0f, 1.0f, false); + } + + for(auto& actor : $actors) { + actor.pos = position_sprite(actor.st, actor.cell, + actor.scale_x, actor.scale_y, false, actor.x, actor.y); + } + + for(auto& fixture : $fixtures) { + fixture.pos = position_sprite(fixture.st, fixture.cell, + fixture.scale_x, fixture.scale_y, false, fixture.x, fixture.y); + } + } + + bool Engine::mouse(float x, float y, Modifiers mods) { + return $ui.mouse(x, y, mods); + } + + sf::Vector2f Engine::position_sprite(textures::SpriteTexture& st, const std::string& cell_name, float scale_x, float scale_y, bool at_mid, float x_diff, float y_diff) { + + auto& cell = $ui.cell_for(cell_name); + float x = float(at_mid ? cell.mid_x : cell.x); + float y = float(at_mid ? cell.mid_y : cell.y); + + sf::Vector2f pos{x + x_diff, y + y_diff}; + st.sprite->setPosition(pos); + st.sprite->setScale({scale_x, scale_y}); + + return pos; + } + + void Engine::render(sf::RenderWindow& window) { + if($floor_sprite.sprite) { + window.draw(*$floor_sprite.sprite); + } + + $ui.render(window); + + for(auto& fixture : $fixtures) { + window.draw(*fixture.st.sprite); + } + + for(auto& actor : $actors) { + window.draw(*actor.st.sprite); + } + + if(DEBUG) $ui.debug_layout(window); + } + + + void Engine::move_actor(const std::string& actor, const std::string& cell_name) { + auto& config = $actors.at($actor_name_ids.at(actor)); + config.cell = cell_name; + config.pos = position_sprite(config.st, config.cell, config.scale_x, config.scale_y, YOU_REMOVED_MID_CELL_IDIOT); + } + + void Engine::animate_actor(const std::string& actor) { + auto& config = $actors.at($actor_name_ids.at(actor)); + config.anim.play(); + } + + void Engine::play_animations() { + for(auto& fixture : $fixtures) { + if(fixture.anim.playing) { + animation::apply(fixture.anim, *fixture.st.sprite, fixture.pos); + } + } + + for(auto& actor : $actors) { + if(actor.anim.playing) { + animation::apply(actor.anim, *actor.st.sprite, actor.pos); + } + } + } + +} diff --git a/scene.hpp b/scene.hpp new file mode 100644 index 0000000..000f6a8 --- /dev/null +++ b/scene.hpp @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include "components.hpp" +#include "textures.hpp" +#include +#include + +namespace scene { + using std::shared_ptr; + using namespace textures; + + struct Element { + textures::SpriteTexture st; + components::Animation anim; + std::string cell; + float scale_x; + float scale_y; + float x; + float y; + bool at_mid=false; + sf::Vector2f pos{0,0}; + }; + + struct Engine { + guecs::UI $ui; + SpriteTexture $floor_sprite; + components::AnimatedScene& $scene; + std::unordered_map $actor_name_ids; + std::vector $fixtures; + std::vector $actors; + + Engine(components::AnimatedScene& scene); + + void init(); + void render(sf::RenderWindow& window); + bool mouse(float x, float y, guecs::Modifiers mods); + sf::Vector2f position_sprite(textures::SpriteTexture& st, const std::string& cell_name, float scale_x, float scale_y, bool at_mid, float x_diff=0.0f, float y_diff=0.0f); + + void move_actor(const std::string& actor, const std::string& cell_name); + void animate_actor(const std::string& actor); + void play_animations(); + }; +}