From 25f7096489eccaa90a71f8ddec19c90020f39aad Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 22 Oct 2025 00:11:36 -0400 Subject: [PATCH] AnimatedScene now defines how a scene with animated sprites and actors is structured and played. --- Makefile | 2 +- assets/animations.json | 4 ++-- assets/bosses.json | 26 ++++++++++++++------------ boss/fight.cpp | 4 ++-- boss/ui.cpp | 31 +++++++++++++------------------ boss/ui.hpp | 7 +++---- components.cpp | 2 +- components.hpp | 7 +++---- tests/components.cpp | 6 +++--- tools/arena.cpp | 2 +- 10 files changed, 43 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index dd046fb..495f32b 100644 --- a/Makefile +++ b/Makefile @@ -72,4 +72,4 @@ money: scc --exclude-dir subprojects arena: - ./builddir/arena + gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args ./builddir/arena diff --git a/assets/animations.json b/assets/animations.json index 62b7d09..95f228b 100644 --- a/assets/animations.json +++ b/assets/animations.json @@ -134,9 +134,9 @@ "max_scale": 0.9, "simple": true, "frames": 1, - "speed": 1.0, + "speed": 0.5, "stationary": false, - "toggled": false, + "toggled": true, "looped": false }, "hairy_spider": { diff --git a/assets/bosses.json b/assets/bosses.json index e8cccc7..a2495c0 100644 --- a/assets/bosses.json +++ b/assets/bosses.json @@ -1,21 +1,23 @@ { "RAT_KING": { "components": [ - {"_type": "BossFight", + {"_type": "AnimatedScene", "background": "test_background", "floor": false, "floor_pos": "floor1", - "player": { - "sprite": "peasant_girl_rear_view", - "start_pos": "player2", - "scale": 0.5, - "mid_cell": false - }, - "boss": { - "start_pos": "boss5", - "scale": 0.6, - "mid_cell": true, - "sprite": "rat_king_boss" + "actors": { + "player": { + "sprite": "peasant_girl_rear_view", + "start_pos": "player2", + "scale": 0.5, + "mid_cell": false + }, + "boss": { + "sprite": "rat_king_boss", + "start_pos": "boss5", + "scale": 0.6, + "mid_cell": true + } }, "fixtures": [ {"name": "torch_fixture", "scale_x": 0.5, "scale_y": 0.5, "cell": "torch1", "x": 66, "y": -50}, diff --git a/boss/fight.cpp b/boss/fight.cpp index 7d421b0..e05bb0e 100644 --- a/boss/fight.cpp +++ b/boss/fight.cpp @@ -84,7 +84,7 @@ namespace boss { break; case ATTACK: { $ui.status(L"PLAYER TURN"); - $ui.move_player(run % 10 < 5 ? "player1" : "player2"); + $ui.move_actor($ui.$player_sprite, "player", run % 10 < 5 ? "player1" : "player2"); int attack_id = std::any_cast(data); boss::System::combat(attack_id); state(State::PLAYER_TURN); @@ -105,7 +105,7 @@ namespace boss { break; case ATTACK: { $ui.status(L"BOSS TURN"); - $ui.move_boss(run % 10 < 5 ? "boss5" : "boss6"); + $ui.$boss_pos = $ui.move_actor($ui.$boss_sprite, "boss", run % 10 < 5 ? "boss5" : "boss6"); $ui.$boss_anim.play(); int attack_id = std::any_cast(data); boss::System::combat(attack_id); diff --git a/boss/ui.cpp b/boss/ui.cpp index e2d6a17..051fff8 100644 --- a/boss/ui.cpp +++ b/boss/ui.cpp @@ -14,10 +14,10 @@ namespace boss { UI::UI(shared_ptr world, Entity boss_id) : $world(world), $boss_id(boss_id), - $scene(world->get($boss_id)), + $scene(world->get($boss_id)), $combat_ui(true) { - std::string sprite_name = $scene.boss["sprite"]; + std::string sprite_name = $scene.actors["boss"]["sprite"]; $boss_sprite = textures::get_sprite(sprite_name); // floor is std::optional @@ -25,7 +25,7 @@ namespace boss { $floor_sprite = textures::get_sprite(*$scene.floor); } - $player_sprite = textures::get_sprite($scene.player["sprite"]); + $player_sprite = textures::get_sprite($scene.actors["player"]["sprite"]); dbc::check(animation::has(sprite_name), "add boss animation to animations.json"); $boss_anim = animation::load(sprite_name); @@ -66,8 +66,8 @@ namespace boss { "[floor4|player5|player6|player7|player8|_]" ); - move_boss($scene.boss["start_pos"]); - move_player($scene.player["start_pos"]); + $boss_pos = move_actor($boss_sprite, "boss", $scene.actors["boss"]["start_pos"]); + move_actor($player_sprite, "player", $scene.actors["player"]["start_pos"]); if($scene.floor) { position_sprite($floor_sprite, $scene.floor_pos, 1.0f, 1.0f, false); @@ -100,13 +100,16 @@ namespace boss { $combat_ui.init(cell.x, cell.y, cell.w, cell.h); } - void 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) { + 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); - st.sprite->setPosition({x + x_diff, y + y_diff}); + 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) { @@ -139,17 +142,9 @@ namespace boss { $arena.show_text("status", msg); } - void UI::move_boss(const std::string& cell_name) { - float scale = $scene.boss["scale"]; - position_sprite($boss_sprite, cell_name, scale, scale, $scene.boss["mid_cell"]); - - auto& cell = $arena.cell_for(cell_name); - $boss_pos = {float(cell.mid_x), float(cell.mid_y)}; - } - - void UI::move_player(const std::string& cell_name) { - float scale = $scene.player["scale"]; - position_sprite($player_sprite, cell_name, scale, scale, $scene.player["mid_cell"]); + sf::Vector2f UI::move_actor(textures::SpriteTexture& st, const std::string& actor, const std::string& cell_name) { + float scale = $scene.actors[actor]["scale"]; + return position_sprite(st, cell_name, scale, scale, $scene.actors[actor]["mid_cell"]); } void UI::play_animations() { diff --git a/boss/ui.hpp b/boss/ui.hpp index 6945d22..aa32c3f 100644 --- a/boss/ui.hpp +++ b/boss/ui.hpp @@ -27,7 +27,7 @@ namespace boss { struct UI { shared_ptr $world = nullptr; Entity $boss_id = NONE; - components::BossFight& $scene; + components::AnimatedScene $scene; gui::CombatUI $combat_ui; SpriteTexture $boss_sprite; SpriteTexture $player_sprite; @@ -44,10 +44,9 @@ namespace boss { void init(); void render(sf::RenderWindow& window); bool mouse(float x, float y, guecs::Modifiers mods); - void 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); + 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_boss(const std::string& cell_name); - void move_player(const std::string& cell_name); + sf::Vector2f move_actor(SpriteTexture& st, const std::string& actor, const std::string& cell_name); void play_animations(); }; } diff --git a/components.cpp b/components.cpp index c8d6c83..8ff6b8b 100644 --- a/components.cpp +++ b/components.cpp @@ -17,7 +17,7 @@ namespace components { void init() { if(!MAP_configured) { - components::enroll(MAP); + components::enroll(MAP); components::enroll(MAP); components::enroll(MAP); components::enroll(MAP); diff --git a/components.hpp b/components.hpp index d2dc3bd..359ba61 100644 --- a/components.hpp +++ b/components.hpp @@ -81,12 +81,11 @@ namespace components { float scale; }; - struct BossFight { + struct AnimatedScene { std::string background; std::optional floor; std::string floor_pos; - json player; - json boss; + json actors; json fixtures; }; @@ -152,7 +151,7 @@ namespace components { using ComponentMap = std::unordered_map; ENROLL_COMPONENT(Tile, display, foreground, background); - ENROLL_COMPONENT(BossFight, background, floor, floor_pos, player, boss, fixtures); + ENROLL_COMPONENT(AnimatedScene, background, floor, floor_pos, actors, fixtures); ENROLL_COMPONENT(Sprite, name, scale); ENROLL_COMPONENT(Curative, hp); ENROLL_COMPONENT(LightSource, strength, radius); diff --git a/tests/components.cpp b/tests/components.cpp index ae54016..e888e4d 100644 --- a/tests/components.cpp +++ b/tests/components.cpp @@ -35,8 +35,8 @@ TEST_CASE("make sure json_mods works", "[components]") { // this confirms that loading something with an optional // field works with the json conversions in json_mods.hpp for(auto& comp_data : config["RAT_KING"]["components"]) { - if(comp_data["_type"] == "BossFight") { - auto comp = components::convert(comp_data); + if(comp_data["_type"] == "AnimatedScene") { + auto comp = components::convert(comp_data); // the boss fight for the rat king doesn't have a stage so false=optional REQUIRE(comp.floor == std::nullopt); } @@ -50,6 +50,6 @@ TEST_CASE("make sure json_mods works", "[components]") { components::configure_entity(world, rat_king, config["RAT_KING"]["components"]); - auto boss = world.get(rat_king); + auto boss = world.get(rat_king); REQUIRE(boss.floor == std::nullopt); } diff --git a/tools/arena.cpp b/tools/arena.cpp index 99dab40..b5fe7f0 100644 --- a/tools/arena.cpp +++ b/tools/arena.cpp @@ -36,7 +36,7 @@ int main(int, char*[]) { gui::routing::Router router; - sound::mute(false); + sound::mute(true); sound::play("ambient_1", true); GameDB::create_level();