From c092b82dfc8f1c564b61c1325f4dd091c73028ce Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Tue, 3 Feb 2026 13:03:38 -0500 Subject: [PATCH] Animator tool now has no UI, it just watches the file to change time and reloads. --- assets/animate2.json | 6 +- tools/animator.cpp | 134 +++++++++++++++++++++---------------------- tools/animator.hpp | 21 +++++-- 3 files changed, 84 insertions(+), 77 deletions(-) diff --git a/assets/animate2.json b/assets/animate2.json index 736820d..3124808 100644 --- a/assets/animate2.json +++ b/assets/animate2.json @@ -6,8 +6,8 @@ "frame_height": 720 }, "sequence": { - "frames": [0, 1], - "durations": [800, 200] + "frames": [0, 1, 0, 1], + "durations": [800, 200, 33, 33] }, "transform": { "min_x": 0.6, @@ -19,7 +19,7 @@ "ease_rate": 5.0, "scaled": true, "toggled": false, - "looped": false + "looped": true } } } diff --git a/tools/animator.cpp b/tools/animator.cpp index c95d6fa..e3ab2ce 100644 --- a/tools/animator.cpp +++ b/tools/animator.cpp @@ -12,19 +12,27 @@ using namespace std::chrono_literals; bool YES_SYNC=true; -animate2::Animate2 anim = animate2::load("assets/animate2.json", "rat_king_boss"); namespace animator { void FSM::init(const std::string &sprite_name) { - $ui.init(sprite_name, *this); + $timer.start(); + $sprite_name = sprite_name; + $ui.init($sprite_name); + $sprite = $ui.get_sprite(); + + // need to keep these aroung + $pos = $sprite->getPosition(); + $scale = $sprite->getScale(); + + $window.setPosition({0,0}); if(YES_SYNC) { $window.setVerticalSyncEnabled(VSYNC); if(FRAME_LIMIT) $window.setFramerateLimit(FRAME_LIMIT); } - $window.setPosition({0,0}); + reload(); } void FSM::event(Event ev, std::any data) { @@ -48,19 +56,18 @@ namespace animator { void FSM::ANIMATE(Event ev) { switch(ev) { case Event::TICK: - // stuff + run_animation(); break; - case Event::PLAY: - if(!anim.playing) anim.play(); + case Event::PLAY_STOP: + if($anim.playing) { + $anim.stop(); + } else { + $anim.play(); + } break; - case Event::STOP: - if(anim.playing) anim.stop(); - break; - case Event::LOOP: - anim.transform.looped = !anim.transform.looped; - break; - case Event::TOGGLE: - anim.transform.toggled = !anim.transform.toggled; + case Event::RELOAD: + reload(); + state(State::START); break; default: state(State::START); @@ -70,6 +77,42 @@ namespace animator { void FSM::END(Event ev) { } + void FSM::run_animation() { + if($anim.playing) { + $anim.update(); + $anim.apply(*$sprite); + $anim.motion(*$sprite, $pos, $scale); + } + } + + void FSM::tick() { + auto [ticks, alpha] = $anim.commit(); + + for(int i = 0; i < ticks; i++) { + event(animator::Event::TICK, {}); + } + + check_update(); + } + + void FSM::check_update() { + if($timer.getElapsedTime().toDuration() > 500ms) { + auto mod_time = std::filesystem::last_write_time("assets/animate2.json"); + + if($last_mod_time < mod_time) { + event(Event::RELOAD); + } + + $timer.restart(); + } + } + + void FSM::reload() { + $anim = animate2::load("assets/animate2.json", $sprite_name); + $anim.play(); + $last_mod_time = std::filesystem::last_write_time("assets/animate2.json"); + } + void FSM::handle_keyboard_mouse() { while(const auto ev = $window.pollEvent()) { using enum game::Event; @@ -78,7 +121,9 @@ namespace animator { switch(gui_ev) { case MOUSE_CLICK: - $ui.mouse(mouse_pos.x, mouse_pos.y, guecs::NO_MODS); + if(!$ui.mouse(mouse_pos.x, mouse_pos.y, guecs::NO_MODS)) { + event(Event::PLAY_STOP); + } break; case MOUSE_MOVE: $ui.mouse(mouse_pos.x, mouse_pos.y, {1 << guecs::ModBit::hover}); @@ -101,41 +146,13 @@ namespace animator { return !in_state(State::END); } - void UI::button(const std::string& name, std::function cb) { - auto comp = $ui.entity(name); - $ui.set(comp, {}); - $ui.set(comp, {guecs::to_wstring(name)}); - $ui.set(comp, {}); - $ui.set(comp, {cb}); - } - - void UI::init(const std::string& sprite_name, FSM& fsm) { - $ui.position(0,0, SCREEN_WIDTH, SCREEN_HEIGHT); - $ui.layout( - "[play|*%=(300,400)viewer|_|_]" - "[stop|_|_|_]" - "[loop|_|_|_]" - "[toggled|_|_|_]"); + void UI::init(const std::string& sprite_name) { + $ui.position(0,0, BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT); + $ui.layout("[=viewer]"); auto viewer = $ui.entity("viewer"); $ui.set(viewer, { sprite_name, 0, false}); - button("stop", [&](auto){ - fsm.event(Event::STOP, {}); - }); - - button("play", [&](auto){ - fsm.event(Event::PLAY, {}); - }); - - button("loop", [&](auto){ - fsm.event(Event::LOOP, {}); - }); - - button("toggled", [&](auto){ - fsm.event(Event::TOGGLE, {}); - }); - $ui.init(); } @@ -153,7 +170,6 @@ namespace animator { } } - int main(int argc, char* argv[]) { shaders::init(); components::init(); @@ -169,31 +185,11 @@ int main(int argc, char* argv[]) { sound::play("ambient_1", true); animator::FSM main; - main.init(argv[1]); - - anim.play(); - - auto sprite = main.$ui.get_sprite(); - - // need to keep these aroung - auto pos = sprite->getPosition(); - auto scale = sprite->getScale(); + main.init(sprite_name); while(main.active()) { - auto [ticks, alpha] = anim.commit(); - - for(int i = 0; i < ticks; i++) { - main.event(animator::Event::TICK, {}); - - if(anim.playing) { - anim.update(); - anim.apply(*sprite); - anim.motion(*sprite, pos, scale); - } - } - + main.tick(); main.render(); - main.handle_keyboard_mouse(); } diff --git a/tools/animator.hpp b/tools/animator.hpp index c2470ec..5eab6be 100644 --- a/tools/animator.hpp +++ b/tools/animator.hpp @@ -3,6 +3,7 @@ #include "gui/event_router.hpp" #include "gui/guecstra.hpp" #include "events.hpp" +#include namespace animator { @@ -14,10 +15,8 @@ namespace animator { enum class Event { TICK=__LINE__, - PLAY=__LINE__, - STOP=__LINE__, - LOOP=__LINE__, - TOGGLE=__LINE__, + PLAY_STOP=__LINE__, + RELOAD=__LINE__, }; struct FSM; @@ -26,7 +25,7 @@ namespace animator { guecs::UI $ui; void button(const std::string& name, std::function cb); - void init(const std::string& sprite_name, FSM& fsm); + void init(const std::string& sprite_name); void render(sf::RenderWindow& window); bool mouse(float x, float y, guecs::Modifiers mods); std::shared_ptr get_sprite(); @@ -36,15 +35,27 @@ namespace animator { UI $ui; gui::routing::Router $router; sf::RenderWindow $window{sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Animation Crafting Tool"}; + sf::Vector2f $pos{0,0}; + sf::Vector2f $scale{0,0}; + std::shared_ptr $sprite = nullptr; + animate2::Animate2 $anim; + std::string $sprite_name=""; + std::filesystem::file_time_type $last_mod_time; + sf::Clock $timer; void init(const std::string &sprite_name); void event(Event ev, std::any data={}); void START(Event ev); void ANIMATE(Event ev); void END(Event ev); + void handle_keyboard_mouse(); void render(); bool active(); + void run_animation(); + void tick(); + void reload(); + void check_update(); }; }