Now the Animation system is no more. Next is cleaning up the quick hacks I needed to finally get rid of it, like animate2::has.

This commit is contained in:
Zed A. Shaw 2026-02-23 23:41:14 -05:00
parent b504afef2a
commit 89ca204f3d
15 changed files with 356 additions and 423 deletions

View file

@ -6,6 +6,7 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include "sound.hpp" #include "sound.hpp"
#include "components.hpp"
constexpr float SUB_FRAME_SENSITIVITY = 0.999f; constexpr float SUB_FRAME_SENSITIVITY = 0.999f;
@ -239,6 +240,9 @@ namespace animate2 {
std::ifstream infile(file); std::ifstream infile(file);
auto data = json::parse(infile); auto data = json::parse(infile);
dbc::check(data.contains(anim_name),
fmt::format("{} animation config does not have animation {}", file, anim_name));
Animate2 anim; Animate2 anim;
animate2::from_json(data[anim_name], anim); animate2::from_json(data[anim_name], anim);
@ -268,4 +272,35 @@ namespace animate2 {
fmt::format("current={} went past end of fame durations.size={}", fmt::format("current={} went past end of fame durations.size={}",
current, durations.size()), location); current, durations.size()), location);
} }
// BUG: BAAADD REMOVE
bool has(const std::string& name) {
using nlohmann::json;
std::ifstream infile("assets/animate2.json");
auto data = json::parse(infile);
return data.contains(name);
}
void configure(DinkyECS::World& world, DinkyECS::Entity entity) {
auto sprite = world.get_if<components::Sprite>(entity);
if(sprite != nullptr && has(sprite->name)) {
world.set<Animate2>(entity, animate2::load("assets/animate2.json", sprite->name));
}
}
void step_animation(DinkyECS::World& world, DinkyECS::Entity entity, sf::Sprite& sprite) {
if(auto anim = world.get_if<Animate2>(entity)) {
if(anim->playing) {
anim->update();
anim->apply(sprite);
}
}
}
void animate_entity(DinkyECS::World &world, DinkyECS::Entity entity) {
if(auto anim = world.get_if<Animate2>(entity)) {
anim->play();
}
}
} }

View file

@ -12,6 +12,7 @@
#include <fmt/core.h> #include <fmt/core.h>
#include "json_mods.hpp" #include "json_mods.hpp"
#include <source_location> #include <source_location>
#include "dinkyecs.hpp"
namespace animate2 { namespace animate2 {
@ -132,6 +133,16 @@ namespace animate2 {
Animate2 load(const std::string &file, const std::string &anim_name); Animate2 load(const std::string &file, const std::string &anim_name);
// BUG: brought over from animation to finish the refactor, but these may not be needed or maybe they go in system.cpp?
bool has(const std::string& name);
void configure(DinkyECS::World& world, DinkyECS::Entity entity);
void step_animation(DinkyECS::World& world, DinkyECS::Entity entity, sf::Sprite& sprite);
void animate_entity(DinkyECS::World &world, DinkyECS::Entity entity);
ENROLL_COMPONENT(Sheet, frames, frame_width, frame_height); ENROLL_COMPONENT(Sheet, frames, frame_width, frame_height);
ENROLL_COMPONENT(Sequence, frames, durations); ENROLL_COMPONENT(Sequence, frames, durations);
ENROLL_COMPONENT(Transform, min_x, min_y, max_x, max_y, ENROLL_COMPONENT(Transform, min_x, min_y, max_x, max_y,

View file

@ -1,273 +0,0 @@
#include "animation.hpp"
#include "rand.hpp"
#include "textures.hpp"
#include <cmath>
namespace components {
void Animation::play() {
if(!playing) {
current = 0;
subframe = 0.0f;
playing = true;
}
}
float Animation::twitching() {
float tick = 1 - std::powf(ease_rate, subframe + 0.0001);
switch(easing) {
case ease::NONE:
return 0.0;
case ease::SINE:
return std::abs(std::sin(subframe * ease_rate));
case ease::OUT_CIRC:
return ease::out_circ(tick);
case ease::OUT_BOUNCE:
return ease::out_bounce(tick);
case ease::IN_OUT_BACK:
return ease::in_out_back(tick);
case ease::RANDOM:
return Random::uniform_real(0.0001f, 1.0f);
case ease::NORM_DIST:
return Random::normal(0.5f, 0.1f);
case ease::LINEAR:
return tick;
default:
dbc::sentinel(
fmt::format("Invalid easing {} given to animation",
int(easing)));
}
}
void Animation::lerp(sf::Vector2f& scale_out, sf::Vector2f& pos_out) {
float tick = std::abs(twitching());
if(stationary) {
switch(motion) {
case ease::SHAKE: {
pos_out.x += std::lerp(min_x, max_x, tick);
} break;
case ease::BOUNCE: {
pos_out.y -= std::lerp(min_y, max_y, tick);
} break;
case ease::RUSH: {
scale_out.x = std::lerp(min_x, max_x, tick);
scale_out.y = std::lerp(min_y, max_y, tick);
pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y);
fmt::println("RUSH pos={},{}; scale={},{}; tic={}", pos_out.x, pos_out.y, scale_out.x, scale_out.y, tick);
} break;
case ease::SQUEEZE: {
scale_out.x *= std::lerp(min_x, max_x, tick);
} break;
case ease::SQUASH: {
scale_out.y *= std::lerp(min_y, max_y, tick);
} break;
case ease::STRETCH: {
scale_out.x = std::lerp(min_x, max_x, tick);
} break;
case ease::GROW: {
scale_out.y = std::lerp(min_y, max_y, tick);
} break;
case ease::SLIDE: {
pos_out.x = std::lerp(min_x, max_x, tick);
pos_out.y = std::lerp(min_y, max_y, tick);
} break;
case ease::NO_MOTION:
break;
default:
dbc::sentinel("Unknown animation.motion setting.");
}
} else {
scale_out.x = std::lerp(scale_out.x * min_x, scale_out.x * max_x, tick);
scale_out.y = std::lerp(scale_out.y * min_y, scale_out.y * max_y, tick);
}
}
void Animation::tween(sf::Vector2f& scale_out, sf::Vector2f& pos_out) {
lerp(scale_out, pos_out);
if(flipped) {
scale_out.x *= -1;
}
}
void Animation::next_frame() {
subframe += speed;
if(looped) {
// it never ends so always do this
current = int(subframe) % frames;
return;
}
current = int(subframe);
playing = current < frames;
if(playing) {
return;
}
// not looped handle not_playing/playing/toggled
if(toggled) {
current = frames - 1;
subframe = float(frames - 1);
} else {
current = 0;
subframe = 0.0f;
}
if(end_cb) end_cb();
}
void Animation::step(sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out) {
dbc::check(rect_out.size.x > 0, "step given rect_out with size.x <= 0, must be >");
dbc::check(rect_out.size.y > 0, "step given rect_out with size.y <= 0, must be >");
next_frame();
if(!simple) {
rect_out.position.x = (current % frames) * frame_width;
}
tween(scale_out, pos_out);
}
bool Animation::apply(sf::Transformable& target, sf::Vector2f pos) {
sf::Vector2f scale{min_x, min_y};
if(playing) {
next_frame();
tween(scale, pos);
target.setPosition(pos);
if(scaled) {
target.setScale(scale);
}
}
return playing;
}
bool Animation::apply(sf::Sprite& sprite, sf::Vector2f pos) {
sf::IntRect rect{{0,0}, {frame_width, frame_height}};
sf::Vector2f scale{min_x, min_y};
if(playing) {
step(scale, pos, rect);
sprite.setPosition(pos);
if(scaled) {
sprite.setScale(scale);
}
sprite.setTextureRect(rect);
}
return playing;
}
bool Animation::apply(sf::View& view_out, sf::Vector2f pos, sf::Vector2f size) {
sf::Vector2f scale{min_x, min_y};
if(playing) {
next_frame();
tween(scale, pos);
view_out.setCenter(pos);
// BUG: is this also needed in the other apply?
if(scaled) {
view_out.setSize({size.x * scale.x, size.y * scale.y});
} else {
view_out.setSize(size);
}
}
return playing;
}
}
namespace animation {
using namespace components;
using namespace textures;
static AnimationManager MGR;
static bool initialized = false;
void rotate(sf::Sprite& target, float degrees) {
target.rotate(sf::degrees(degrees));
}
void center(sf::Sprite& target, sf::Vector2f pos) {
auto bounds = target.getLocalBounds();
target.setPosition({pos.x + bounds.size.x / 2,
pos.y + bounds.size.y / 2});
target.setOrigin({bounds.size.x / 2, bounds.size.y / 2});
}
void init() {
if(!initialized) {
auto animations = settings::get("animations");
auto config = settings::get("config");
auto& sprites = config["sprites"];
for(auto& [name, data] : animations.json().items()) {
try {
auto anim = components::convert<Animation>(data);
if(!sprites.contains(name)) {
fmt::println("animation '{}' doesn't have sprite, spelled wrong in config.json?", name);
} else {
auto& sprite_config = sprites[name];
anim.frame_width = sprite_config["frame_width"];
anim.frame_height = sprite_config["frame_height"];
dbc::check(anim.frame_width > 0 && anim.frame_height > 0,
fmt::format("invalid frame width/height for animation: {}",
name));
}
MGR.animations.insert_or_assign(name, anim);
} catch(...) {
dbc::log(fmt::format("error in sprite config: {}", name));
throw;
}
}
initialized = true;
}
}
bool has(const std::string& name) {
return MGR.animations.contains(name);
}
Animation load(const std::string& name, const std::string& state) {
dbc::check(initialized, "You forgot to initialize animation.");
return MGR.animations.at(name + state);
}
void configure(DinkyECS::World& world, DinkyECS::Entity entity) {
auto sprite = world.get_if<Sprite>(entity);
if(sprite != nullptr && animation::has(sprite->name)) {
world.set<Animation>(entity, animation::load(sprite->name));
}
}
void step_animation(DinkyECS::World& world, DinkyECS::Entity entity, sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out) {
if(auto animation = world.get_if<components::Animation>(entity)) {
if(animation->playing) animation->step(scale_out, pos_out, rect_out);
}
}
void animate_entity(DinkyECS::World &world, DinkyECS::Entity entity) {
if(world.has<Animation>(entity)) {
auto& animation = world.get<Animation>(entity);
animation.play();
}
}
}

View file

@ -1,22 +0,0 @@
#pragma once
#include "components.hpp"
#include "easings.hpp"
#include "dinkyecs.hpp"
#include <SFML/Graphics/Rect.hpp>
#include <SFML/Graphics/Sprite.hpp>
namespace animation {
struct AnimationManager {
std::unordered_map<std::string, components::Animation> animations;
};
void rotate(sf::Sprite& target, float degrees);
void center(sf::Sprite& target, sf::Vector2f pos);
void init();
components::Animation load(const std::string& name, const std::string& state="");
bool has(const std::string& name);
void configure(DinkyECS::World& world, DinkyECS::Entity entity);
void step_animation(DinkyECS::World& world, DinkyECS::Entity entity, sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out);
void animate_entity(DinkyECS::World &world, DinkyECS::Entity entity);
}

View file

@ -197,6 +197,302 @@
"open": [], "open": [],
"close": [] "close": []
} }
},
"burning_animation": {
"sheet": {
"frames": 3,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0,1,2], "durations": [5,5,5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"male_hand": {
"sheet": {
"frames": 1,
"frame_width": 900,
"frame_height": 600
},
"sequences": {
"idle": {"frames": [0], "durations": [5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"lightning_animation": {
"sheet": {
"frames": 5,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0,1,2,3,4], "durations": [5,5,5,5,5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"gold_savior": {
"sheet": {
"frames": 1,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0], "durations": [5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"armored_knight": {
"sheet": {
"frames": 1,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0], "durations": [5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"axe_ranger": {
"sheet": {
"frames": 1,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0], "durations": [5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"rat_with_sword": {
"sheet": {
"frames": 1,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0], "durations": [5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"hairy_spider": {
"sheet": {
"frames": 1,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0], "durations": [5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
},
"test_boss": {
"sheet": {
"frames": 1,
"frame_width": 256,
"frame_height": 256
},
"sequences": {
"idle": {"frames": [0], "durations": [5] }
},
"transforms": {
"basic": {
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.0,
"max_y": 1.0,
"flipped": false,
"scaled": false,
"toggled": false,
"looped": false,
"relative": false,
"easing": "none",
"motion": "move_none"
}
},
"forms": {
"idle": ["idle", "basic"]
},
"sounds": {
"idle": [],
"open": [],
"close": []
}
} }
} }

View file

@ -252,23 +252,5 @@
"toggled": false, "toggled": false,
"flipped": false, "flipped": false,
"looped": true "looped": true
},
"test_floor": {
"_type": "Animation",
"easing": 2,
"motion": 0,
"ease_rate": 0.5,
"min_x": 1.0,
"min_y": 1.0,
"max_x": 1.01,
"max_y": 1.01,
"simple": true,
"frames": 1,
"speed": 0.01,
"scaled": true,
"stationary": true,
"toggled": false,
"flipped": false,
"looped": false
} }
} }

View file

@ -29,7 +29,6 @@ namespace components {
components::enroll<LightSource>(MAP); components::enroll<LightSource>(MAP);
components::enroll<Device>(MAP); components::enroll<Device>(MAP);
components::enroll<Sprite>(MAP); components::enroll<Sprite>(MAP);
components::enroll<Animation>(MAP);
components::enroll<Sound>(MAP); components::enroll<Sound>(MAP);
components::enroll<Collision>(MAP); components::enroll<Collision>(MAP);
MAP_configured = true; MAP_configured = true;

View file

@ -141,44 +141,6 @@ namespace components {
std::string death; std::string death;
}; };
struct Animation {
float min_x = 1.0f;
float min_y = 1.0f;
float max_x = 1.0f;
float max_y = 1.0f;
bool simple = true;
int frames = 1;
float speed = 0.3f;
ease::Style easing = ease::IN_OUT_BACK;
ease::Motion motion = ease::RUSH;
float ease_rate = 0.5f;
bool scaled = false;
bool stationary = false;
bool toggled = false;
bool looped = false;
bool flipped = false;
std::function<void()> end_cb = nullptr;
int current = 0;
bool playing = false;
float subframe = 0.0f;
// BUG: this is weirdly not used in most animations but also named wrong should be frame_width
int frame_width = -1;
int frame_height = -1;
bool apply(sf::Sprite& target, sf::Vector2f pos);
bool apply(sf::View& view_out, sf::Vector2f pos, sf::Vector2f size);
bool apply(sf::Transformable& target, sf::Vector2f pos);
void lerp(sf::Vector2f& scale_out, sf::Vector2f& pos_out);
void tween(sf::Vector2f& scale_out, sf::Vector2f& pos_out);
void next_frame();
void play();
float twitching();
void step(sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out);
};
struct Player { struct Player {
DinkyECS::Entity entity; DinkyECS::Entity entity;
}; };
@ -201,10 +163,6 @@ namespace components {
ENROLL_COMPONENT(Combat, hp, max_hp, ap_delta, max_ap, damage, dead); ENROLL_COMPONENT(Combat, hp, max_hp, ap_delta, max_ap, damage, dead);
ENROLL_COMPONENT(Device, config, events); ENROLL_COMPONENT(Device, config, events);
ENROLL_COMPONENT(Storyboard, image, audio, layout, beats); ENROLL_COMPONENT(Storyboard, image, audio, layout, beats);
ENROLL_COMPONENT(Animation, min_x, min_y,
max_x, max_y, simple, frames,
speed, easing, motion, ease_rate,
scaled, stationary, toggled, looped, flipped);
ENROLL_COMPONENT(Sound, attack, death); ENROLL_COMPONENT(Sound, attack, death);
ENROLL_COMPONENT(Collision, has); ENROLL_COMPONENT(Collision, has);

View file

@ -3,7 +3,6 @@
#include "sound.hpp" #include "sound.hpp"
#include "autowalker.hpp" #include "autowalker.hpp"
#include "ai.hpp" #include "ai.hpp"
#include "animation.hpp"
#include <iostream> #include <iostream>
#include "shaders.hpp" #include "shaders.hpp"
#include "backend.hpp" #include "backend.hpp"
@ -18,7 +17,6 @@ int main(int argc, char* argv[]) {
components::init(); components::init();
guecs::init(&backend); guecs::init(&backend);
ai::init("ai"); ai::init("ai");
animation::init();
GameDB::init(); GameDB::init();
cinematic::init(); cinematic::init();

View file

@ -88,8 +88,6 @@ sources = [
'ai.cpp', 'ai.cpp',
'ai_debug.cpp', 'ai_debug.cpp',
'animate2.cpp', 'animate2.cpp',
'animation.cpp',
'animation.cpp',
'autowalker.cpp', 'autowalker.cpp',
'backend.cpp', 'backend.cpp',
'battle.cpp', 'battle.cpp',
@ -141,7 +139,6 @@ sources = [
executable('runtests', sources + [ executable('runtests', sources + [
'tests/ai.cpp', 'tests/ai.cpp',
'tests/animate2.cpp', 'tests/animate2.cpp',
'tests/animation.cpp',
'tests/base.cpp', 'tests/base.cpp',
'tests/battle.cpp', 'tests/battle.cpp',
'tests/camera.cpp', 'tests/camera.cpp',

View file

@ -11,7 +11,7 @@
#include "textures.hpp" #include "textures.hpp"
#include "systems.hpp" #include "systems.hpp"
#include "shaders.hpp" #include "shaders.hpp"
#include "animation.hpp" #include "animate2.hpp"
using namespace fmt; using namespace fmt;
using std::make_unique, std::shared_ptr; using std::make_unique, std::shared_ptr;
@ -202,12 +202,13 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
effect->setUniform("darkness", level); effect->setUniform("darkness", level);
} }
animation::step_animation(*world, rec.entity, scale, position, in_texture); sf_sprite->setScale(scale);
sf_sprite->setPosition(position);
animate2::step_animation(*world, rec.entity, *sf_sprite);
sf_sprite->setOrigin(origin); sf_sprite->setOrigin(origin);
sf_sprite->setScale(scale);
sf_sprite->setTextureRect(in_texture); sf_sprite->setTextureRect(in_texture);
sf_sprite->setPosition(position);
target.draw(*sf_sprite, effect.get()); target.draw(*sf_sprite, effect.get());
} }

View file

@ -18,7 +18,7 @@
#include "inventory.hpp" #include "inventory.hpp"
#include "game_level.hpp" #include "game_level.hpp"
#include "events.hpp" #include "events.hpp"
#include "animation.hpp" #include "animate2.hpp"
using std::string; using std::string;
using namespace fmt; using namespace fmt;
@ -279,7 +279,7 @@ void System::combat(int attack_id) {
if(enemy_action == "kill_enemy") { if(enemy_action == "kill_enemy") {
result.enemy_did = enemy.combat->attack(player_combat); result.enemy_did = enemy.combat->attack(player_combat);
animation::animate_entity(world, enemy.entity); animate2::animate_entity(world, enemy.entity);
} }
world.send<game::Event>(game::Event::COMBAT, enemy.entity, result); world.send<game::Event>(game::Event::COMBAT, enemy.entity, result);
@ -654,13 +654,13 @@ void System::clear_attack() {
auto world = GameDB::current_world(); auto world = GameDB::current_world();
std::vector<Entity> dead_anim; std::vector<Entity> dead_anim;
world->query<Animation, Temporary>([&](auto ent, auto& anim, auto&) { world->query<animate2::Animate2, Temporary>([&](auto ent, auto& anim, auto&) {
if(!anim.playing) dead_anim.push_back(ent); if(!anim.playing) dead_anim.push_back(ent);
}); });
for(auto ent : dead_anim) { for(auto ent : dead_anim) {
world->remove<Sprite>(ent); world->remove<Sprite>(ent);
world->remove<Animation>(ent); world->remove<animate2::Animate2>(ent);
world->remove<SpriteEffect>(ent); world->remove<SpriteEffect>(ent);
remove_from_world(ent); remove_from_world(ent);
} }
@ -686,9 +686,9 @@ void System::spawn_attack(World& world, int attack_id, DinkyECS::Entity enemy) {
// also add the same effect to the enemy // also add the same effect to the enemy
world.set<SpriteEffect>(enemy, {50, shader}); world.set<SpriteEffect>(enemy, {50, shader});
auto anim = animation::load(effect); auto anim = animate2::load("assets/animate2.json", effect);
anim.play(); anim.play();
world.set<Animation>(effect_id, anim); world.set<animate2::Animate2>(effect_id, anim);
drop_item(effect_id); drop_item(effect_id);
} }

View file

@ -11,7 +11,6 @@
#include "sound.hpp" #include "sound.hpp"
#include "components.hpp" #include "components.hpp"
using namespace components; using namespace components;
using namespace textures; using namespace textures;
using namespace std::chrono_literals; using namespace std::chrono_literals;

View file

@ -1,48 +0,0 @@
#include <catch2/catch_test_macros.hpp>
#include "animation.hpp"
#include "textures.hpp"
#include "config.hpp"
#include "rand.hpp"
using namespace components;
using namespace textures;
TEST_CASE("animation easing tests", "[animation]") {
Animation anim;
anim.easing = ease::NONE;
float res = anim.twitching();
REQUIRE(res == 0.0);
anim.easing = ease::SINE;
anim.subframe = 1.0f;
res = anim.twitching();
REQUIRE(!std::isnan(res));
anim.easing = ease::OUT_CIRC;
res = anim.twitching();
REQUIRE(!std::isnan(res));
anim.easing = ease::OUT_BOUNCE;
res = anim.twitching();
REQUIRE(!std::isnan(res));
anim.easing = ease::IN_OUT_BACK;
res = anim.twitching();
REQUIRE(!std::isnan(res));
}
TEST_CASE("animation utility API", "[animation]") {
textures::init();
animation::init();
auto blanket = textures::get_sprite("ritual_crafting_area");
auto anim = animation::load("ritual_crafting_area");
anim.play();
while(anim.apply(*blanket.sprite, {0,0})) {
fmt::println("animation: {}", anim.subframe);
}
}

View file

@ -8,7 +8,7 @@
#include "textures.hpp" #include "textures.hpp"
#include "inventory.hpp" #include "inventory.hpp"
#include "systems.hpp" #include "systems.hpp"
#include "animation.hpp" #include "animate2.hpp"
using namespace fmt; using namespace fmt;
using namespace components; using namespace components;
@ -101,7 +101,7 @@ DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, j
} }
System::set_position(world, $collision, item, {pos.x, pos.y}); System::set_position(world, $collision, item, {pos.x, pos.y});
animation::configure(world, item); animate2::configure(world, item);
return item; return item;
} }