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:
parent
b504afef2a
commit
89ca204f3d
15 changed files with 356 additions and 423 deletions
35
animate2.cpp
35
animate2.cpp
|
|
@ -6,6 +6,7 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "sound.hpp"
|
||||
#include "components.hpp"
|
||||
|
||||
constexpr float SUB_FRAME_SENSITIVITY = 0.999f;
|
||||
|
||||
|
|
@ -239,6 +240,9 @@ namespace animate2 {
|
|||
std::ifstream infile(file);
|
||||
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::from_json(data[anim_name], anim);
|
||||
|
||||
|
|
@ -268,4 +272,35 @@ namespace animate2 {
|
|||
fmt::format("current={} went past end of fame durations.size={}",
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
11
animate2.hpp
11
animate2.hpp
|
|
@ -12,6 +12,7 @@
|
|||
#include <fmt/core.h>
|
||||
#include "json_mods.hpp"
|
||||
#include <source_location>
|
||||
#include "dinkyecs.hpp"
|
||||
|
||||
namespace animate2 {
|
||||
|
||||
|
|
@ -132,6 +133,16 @@ namespace animate2 {
|
|||
|
||||
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(Sequence, frames, durations);
|
||||
ENROLL_COMPONENT(Transform, min_x, min_y, max_x, max_y,
|
||||
|
|
|
|||
273
animation.cpp
273
animation.cpp
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -197,6 +197,302 @@
|
|||
"open": [],
|
||||
"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": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,23 +252,5 @@
|
|||
"toggled": false,
|
||||
"flipped": false,
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ namespace components {
|
|||
components::enroll<LightSource>(MAP);
|
||||
components::enroll<Device>(MAP);
|
||||
components::enroll<Sprite>(MAP);
|
||||
components::enroll<Animation>(MAP);
|
||||
components::enroll<Sound>(MAP);
|
||||
components::enroll<Collision>(MAP);
|
||||
MAP_configured = true;
|
||||
|
|
|
|||
|
|
@ -141,44 +141,6 @@ namespace components {
|
|||
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 {
|
||||
DinkyECS::Entity entity;
|
||||
};
|
||||
|
|
@ -201,10 +163,6 @@ namespace components {
|
|||
ENROLL_COMPONENT(Combat, hp, max_hp, ap_delta, max_ap, damage, dead);
|
||||
ENROLL_COMPONENT(Device, config, events);
|
||||
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(Collision, has);
|
||||
|
||||
|
|
|
|||
2
main.cpp
2
main.cpp
|
|
@ -3,7 +3,6 @@
|
|||
#include "sound.hpp"
|
||||
#include "autowalker.hpp"
|
||||
#include "ai.hpp"
|
||||
#include "animation.hpp"
|
||||
#include <iostream>
|
||||
#include "shaders.hpp"
|
||||
#include "backend.hpp"
|
||||
|
|
@ -18,7 +17,6 @@ int main(int argc, char* argv[]) {
|
|||
components::init();
|
||||
guecs::init(&backend);
|
||||
ai::init("ai");
|
||||
animation::init();
|
||||
GameDB::init();
|
||||
cinematic::init();
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,6 @@ sources = [
|
|||
'ai.cpp',
|
||||
'ai_debug.cpp',
|
||||
'animate2.cpp',
|
||||
'animation.cpp',
|
||||
'animation.cpp',
|
||||
'autowalker.cpp',
|
||||
'backend.cpp',
|
||||
'battle.cpp',
|
||||
|
|
@ -141,7 +139,6 @@ sources = [
|
|||
executable('runtests', sources + [
|
||||
'tests/ai.cpp',
|
||||
'tests/animate2.cpp',
|
||||
'tests/animation.cpp',
|
||||
'tests/base.cpp',
|
||||
'tests/battle.cpp',
|
||||
'tests/camera.cpp',
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "textures.hpp"
|
||||
#include "systems.hpp"
|
||||
#include "shaders.hpp"
|
||||
#include "animation.hpp"
|
||||
#include "animate2.hpp"
|
||||
|
||||
using namespace fmt;
|
||||
using std::make_unique, std::shared_ptr;
|
||||
|
|
@ -202,12 +202,13 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
|
|||
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->setScale(scale);
|
||||
sf_sprite->setTextureRect(in_texture);
|
||||
sf_sprite->setPosition(position);
|
||||
|
||||
target.draw(*sf_sprite, effect.get());
|
||||
}
|
||||
|
|
|
|||
12
systems.cpp
12
systems.cpp
|
|
@ -18,7 +18,7 @@
|
|||
#include "inventory.hpp"
|
||||
#include "game_level.hpp"
|
||||
#include "events.hpp"
|
||||
#include "animation.hpp"
|
||||
#include "animate2.hpp"
|
||||
|
||||
using std::string;
|
||||
using namespace fmt;
|
||||
|
|
@ -279,7 +279,7 @@ void System::combat(int attack_id) {
|
|||
|
||||
if(enemy_action == "kill_enemy") {
|
||||
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);
|
||||
|
|
@ -654,13 +654,13 @@ void System::clear_attack() {
|
|||
auto world = GameDB::current_world();
|
||||
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);
|
||||
});
|
||||
|
||||
for(auto ent : dead_anim) {
|
||||
world->remove<Sprite>(ent);
|
||||
world->remove<Animation>(ent);
|
||||
world->remove<animate2::Animate2>(ent);
|
||||
world->remove<SpriteEffect>(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
|
||||
world.set<SpriteEffect>(enemy, {50, shader});
|
||||
|
||||
auto anim = animation::load(effect);
|
||||
auto anim = animate2::load("assets/animate2.json", effect);
|
||||
anim.play();
|
||||
world.set<Animation>(effect_id, anim);
|
||||
world.set<animate2::Animate2>(effect_id, anim);
|
||||
|
||||
drop_item(effect_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include "sound.hpp"
|
||||
#include "components.hpp"
|
||||
|
||||
|
||||
using namespace components;
|
||||
using namespace textures;
|
||||
using namespace std::chrono_literals;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
#include "textures.hpp"
|
||||
#include "inventory.hpp"
|
||||
#include "systems.hpp"
|
||||
#include "animation.hpp"
|
||||
#include "animate2.hpp"
|
||||
|
||||
using namespace fmt;
|
||||
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});
|
||||
animation::configure(world, item);
|
||||
animate2::configure(world, item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue