Check in... animations are roughly half built
This commit is contained in:
parent
47e823d5b9
commit
d74635ee4e
|
@ -1,67 +1,73 @@
|
|||
#include "Animation.h"
|
||||
|
||||
Animation::Animation(float _d, void* _t, std::function<void()> _cb, bool _l)
|
||||
:duration(_d), target(_t), callback(_cb), loop(_l), elapsed(0.0f) {}
|
||||
|
||||
// linear interpolation constructor
|
||||
template<typename T>
|
||||
Animation<T>::Animation(float _d, T _ev, T* _t, std::function<void()> _cb, bool _l)
|
||||
:duration(_d), endvalue(_ev), target(_t), callback(_cb), loop(_l),
|
||||
index(-1), startvalue(*_t), elapsed(0.0f) {}
|
||||
LerpAnimation<T>::LerpAnimation(float _d, T _ev, T* _t, std::function<void()> _cb, bool _l)
|
||||
:Animation(_d, _t, _cb, _l), //duration(_d), target(_t), callback(_cb), loop(_l),elapsed(0.0f),
|
||||
startvalue(*_t), endvalue(_ev) {}
|
||||
|
||||
// discrete values constructor
|
||||
template<typename T>
|
||||
Animation<T>::Animation(float _d, std::vector<T> _v, T* _t, std::function<void()> _cb, bool _l)
|
||||
:duration(_d), target(_t), callback(_cb), values(_v), loop(_l),
|
||||
index(0), startvalue(*_t), elapsed(0.0f), nonelapsed(0.0f) {
|
||||
DiscreteAnimation<T>::DiscreteAnimation(float _d, std::vector<T> _v, T* _t, std::function<void()> _cb, bool _l)
|
||||
:Animation(_d, _t, _cb, _l), //duration(_d), target(_t), callback(_cb), loop(_l), elapsed(0.0f),
|
||||
index(0), nonelapsed(0.0f), values(_v) {
|
||||
timestep = _v.size() / _d;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Animation<T>::~Animation() {
|
||||
/* // don't call virtual functions (like cancel()) from base class destructor
|
||||
* // child classes destructors' are called first anyway
|
||||
Animation::~Animation() {
|
||||
// deconstructor sets target to desired end state (no partial values)
|
||||
cancel();
|
||||
}
|
||||
*/
|
||||
|
||||
template<>
|
||||
void Animation<std::string>::lerp() {
|
||||
*target = endvalue.substr(0, endvalue.length() * (elapsed / duration));
|
||||
void LerpAnimation<std::string>::lerp() {
|
||||
*(std::string*)target = endvalue.substr(0, endvalue.length() * (elapsed / duration));
|
||||
}
|
||||
|
||||
template<>
|
||||
void Animation<int>::lerp() {
|
||||
void LerpAnimation<int>::lerp() {
|
||||
int delta = endvalue - startvalue;
|
||||
*target = startvalue + (elapsed / duration * delta);
|
||||
*(int*)target = startvalue + (elapsed / duration * delta);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Animation<float>::lerp() {
|
||||
void LerpAnimation<float>::lerp() {
|
||||
int delta = endvalue - startvalue;
|
||||
*target = startvalue + (elapsed / duration * delta);
|
||||
*(float*)target = startvalue + (elapsed / duration * delta);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Animation<sf::Vector2f>::lerp() {
|
||||
void LerpAnimation<sf::Vector2f>::lerp() {
|
||||
int delta_x = endvalue.x - startvalue.x;
|
||||
int delta_y = endvalue.y - startvalue.y;
|
||||
target->x = startvalue.x + (elapsed / duration * delta_x);
|
||||
target->y = startvalue.y + (elapsed / duration * delta_y);
|
||||
((sf::Vector2f*)target)->x = startvalue.x + (elapsed / duration * delta_x);
|
||||
((sf::Vector2f*)target)->y = startvalue.y + (elapsed / duration * delta_y);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Animation<sf::Vector2i>::lerp() {
|
||||
void LerpAnimation<sf::Vector2i>::lerp() {
|
||||
int delta_x = endvalue.x - startvalue.y;
|
||||
int delta_y = endvalue.y - startvalue.y;
|
||||
target->x = startvalue.x + (elapsed / duration * delta_x);
|
||||
target->y = startvalue.y + (elapsed / duration * delta_y);
|
||||
((sf::Vector2i*)target)->x = startvalue.x + (elapsed / duration * delta_x);
|
||||
((sf::Vector2i*)target)->y = startvalue.y + (elapsed / duration * delta_y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Animation<T>::step(float delta)
|
||||
{
|
||||
if (index == -1) {
|
||||
// lerp function
|
||||
void LerpAnimation<T>::step(float delta) {
|
||||
elapsed += delta;
|
||||
lerp();
|
||||
if (isDone()) cancel(); //use the exact value, not my math
|
||||
}
|
||||
else {
|
||||
|
||||
template<typename T>
|
||||
void DiscreteAnimation<T>::step(float delta)
|
||||
{
|
||||
nonelapsed += delta;
|
||||
if (nonelapsed < timestep) return;
|
||||
if (index == values.size() - 1) return;
|
||||
|
@ -69,13 +75,19 @@ void Animation<T>::step(float delta)
|
|||
nonelapsed = 0; // or should it -= timestep?
|
||||
index++;
|
||||
*target = values[index];
|
||||
}
|
||||
if (isDone()) cancel(); //use the exact value, not my math
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Animation<T>::cancel() {
|
||||
if (index == -1)
|
||||
void LerpAnimation<T>::cancel() {
|
||||
*target = endvalue;
|
||||
else
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void DiscreteAnimation<T>::cancel() {
|
||||
*target = values[values.size() - 1];
|
||||
}
|
||||
|
||||
bool Animation::isDone() {
|
||||
return elapsed + Animation::EPSILON >= duration;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,44 @@
|
|||
#pragma once
|
||||
#include "Common.h"
|
||||
|
||||
template<typename T>
|
||||
class Animation
|
||||
{
|
||||
protected:
|
||||
static constexpr float EPSILON = 0.05;
|
||||
T startvalue, endvalue;
|
||||
int index;
|
||||
float duration, elapsed, nonelapsed, timestep;
|
||||
T* target;
|
||||
std::vector<T> values;
|
||||
float duration, elapsed;
|
||||
void* target;
|
||||
std::function<void()> callback;
|
||||
bool loop;
|
||||
public:
|
||||
Animation(float, T, T*, std::function<void()>, bool); // lerp
|
||||
Animation(float, std::vector<T>, T*, std::function<void()>, bool); // discrete
|
||||
~Animation();
|
||||
void lerp();
|
||||
void step(float);
|
||||
void cancel();
|
||||
//Animation(float, T, T*, std::function<void()>, bool); // lerp
|
||||
//Animation(float, std::vector<T>, T*, std::function<void()>, bool); // discrete
|
||||
Animation(float, void*, std::function<void()>, bool);
|
||||
virtual void step(float) = 0;
|
||||
virtual void cancel() = 0;
|
||||
bool isDone();
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class LerpAnimation: public Animation
|
||||
{
|
||||
T startvalue, endvalue;
|
||||
void lerp();
|
||||
public:
|
||||
~LerpAnimation() { cancel(); }
|
||||
LerpAnimation(float, T, T*, std::function<void()>, bool);
|
||||
void step(float) override final;
|
||||
void cancel() override final;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class DiscreteAnimation: public Animation
|
||||
{
|
||||
std::vector<T> values;
|
||||
float nonelapsed, timestep;
|
||||
int index;
|
||||
public:
|
||||
DiscreteAnimation(float, std::vector<T>, T*, std::function<void()>, bool);
|
||||
~DiscreteAnimation() { cancel(); }
|
||||
void step(float) override final;
|
||||
void cancel() override final;
|
||||
};
|
||||
|
|
|
@ -27,6 +27,8 @@ GameEngine::GameEngine()
|
|||
scenes["py"] = new PythonScene(this, "TestScene");
|
||||
|
||||
IndexSprite::game = this;
|
||||
|
||||
clock.restart();
|
||||
}
|
||||
|
||||
Scene* GameEngine::currentScene() { return scenes[scene]; }
|
||||
|
@ -38,6 +40,7 @@ sf::RenderWindow & GameEngine::getWindow() { return window; }
|
|||
|
||||
void GameEngine::run()
|
||||
{
|
||||
clock.restart();
|
||||
while (running)
|
||||
{
|
||||
currentScene()->update();
|
||||
|
@ -47,6 +50,7 @@ void GameEngine::run()
|
|||
}
|
||||
currentScene()->sRender();
|
||||
currentFrame++;
|
||||
frameTime = clock.restart().asSeconds();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ class GameEngine
|
|||
bool paused = false;
|
||||
int currentFrame = 0;
|
||||
sf::View visible;
|
||||
sf::Clock clock;
|
||||
float frameTime;
|
||||
|
||||
public:
|
||||
GameEngine();
|
||||
|
@ -29,6 +31,7 @@ public:
|
|||
void run();
|
||||
void sUserInput();
|
||||
int getFrame() { return currentFrame; }
|
||||
float getFrameTime() { return frameTime; }
|
||||
sf::View getView() { return visible; }
|
||||
|
||||
// global textures for scripts to access
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
std::map<std::string, UIMenu*> McRFPy_API::menus;
|
||||
std::map<std::string, Grid*> McRFPy_API::grids;
|
||||
std::map<std::string, PyObject*> McRFPy_API::callbacks;
|
||||
std::list<Animation*> McRFPy_API::animations;
|
||||
|
||||
EntityManager McRFPy_API::entities;
|
||||
|
||||
static PyMethodDef mcrfpyMethods[] = {
|
||||
|
@ -46,6 +48,18 @@ static PyMethodDef mcrfpyMethods[] = {
|
|||
{"modGrid", McRFPy_API::_modGrid, METH_VARARGS,
|
||||
"call with a Grid object to update all fields"},
|
||||
|
||||
{"createAnimation", McRFPy_API::_createAnimation, METH_VARARGS,
|
||||
"Create a new animation:\n"
|
||||
"createAnimation(duration:float, parent:string, target_type:string, target_id:string or int, field:string, callback:function, loop:bool, frames:list)\n"
|
||||
"duration: total animation time in seconds\n"
|
||||
"parent: the name of a UI menu or grid\n"
|
||||
"target_type: 'caption', 'button', 'sprite', or 'entity'\n"
|
||||
"target_id: integer index of the caption or button, or string ID of entity\n"
|
||||
"field: what to animate. 'position', 'size', 'bgcolor', 'textcolor' or 'sprite'\n"
|
||||
"callback: called when the animation completes\n"
|
||||
"loop: if True, animation repeats; if False, animation is deleted\n"
|
||||
"frames: if animating a sprite, list the frames. For other data types, the value will change in discrete steps at a rate of duration/len(frames).\n"},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
static std::map<std::string, UIMenu*> menus;
|
||||
static EntityManager entities; // this is also kinda good, entities not on the current grid can still act (like monsters following you through doors??)
|
||||
static std::map<std::string, Grid*> grids;
|
||||
static std::list<Animation*> animations;
|
||||
|
||||
static std::map<std::string, PyObject*> callbacks;
|
||||
|
||||
|
@ -69,6 +70,8 @@ public:
|
|||
static PyObject* _listGrids(PyObject*, PyObject*);
|
||||
static PyObject* _modGrid(PyObject*, PyObject*);
|
||||
|
||||
static PyObject* _createAnimation(PyObject*, PyObject*);
|
||||
|
||||
static PyObject* _registerPyAction(PyObject*, PyObject*);
|
||||
|
||||
// Jank Functionality
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "PythonScene.h"
|
||||
#include "ActionCode.h"
|
||||
#include "McRFPy_API.h"
|
||||
#include "Animation.h"
|
||||
|
||||
PythonScene::PythonScene(GameEngine* g, std::string pymodule)
|
||||
: Scene(g) {
|
||||
|
@ -42,6 +43,58 @@ PythonScene::PythonScene(GameEngine* g, std::string pymodule)
|
|||
McRFPy_API::executePyString(pymodule + ".start()");
|
||||
}
|
||||
|
||||
void PythonScene::animate() {
|
||||
auto frametime = game->getFrameTime();
|
||||
auto it = McRFPy_API::animations.begin();
|
||||
while (it != animations.end()) {
|
||||
(*it)->step(frametime);
|
||||
if ((*it)->isDone()) {
|
||||
auto prev = it;
|
||||
it++;
|
||||
animations.erase(prev);
|
||||
} else it++;
|
||||
}
|
||||
/* // workin on it
|
||||
for (auto p : animations) {
|
||||
if (p.first == "int") {
|
||||
((Animation<int>)p.second).step(frametime);
|
||||
} else if (p.first == "string") {
|
||||
((Animation<std::string>)p.second).step(frametime);
|
||||
} else if (p.first == "float") {
|
||||
((Animation<float>)p.second).step(frametime);
|
||||
} else if (p.first == "vector2f") {
|
||||
((Animation<sf::Vector2f>)p.second).step(frametime);
|
||||
} else if (p.first == "vector2i") {
|
||||
((Animation<sf::Vector2i>)p.second).step(frametime);
|
||||
} else if (p.first == "color") {
|
||||
((Animation<int>)p.second).step(frametime); // TODO
|
||||
} else {
|
||||
std::cout << "Animation has label " << p.first << "; no type found" << std::endl;
|
||||
}
|
||||
}
|
||||
auto it = animations.begin();
|
||||
while (it != animations.end()) {
|
||||
bool done = false;
|
||||
if (p.first == "int") {
|
||||
((Animation<int>)p.second).step(frametime);
|
||||
} else if (p.first == "string") {
|
||||
if ((Animation<std::string>)p.second).isDone()
|
||||
delete (Animation<std::string>)p.second
|
||||
} else if (p.first == "float") {
|
||||
((Animation<float>)p.second).step(frametime);
|
||||
} else if (p.first == "vector2f") {
|
||||
((Animation<sf::Vector2f>)p.second).step(frametime);
|
||||
} else if (p.first == "vector2i") {
|
||||
((Animation<sf::Vector2i>)p.second).step(frametime);
|
||||
} else if (p.first == "color") {
|
||||
((Animation<int>)p.second).step(frametime); // TODO
|
||||
if ((*it).second.isDone()) {
|
||||
animations.erase(it++);
|
||||
} else { it++; }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void PythonScene::update() {
|
||||
McRFPy_API::entities.update();
|
||||
|
||||
|
@ -57,6 +110,7 @@ void PythonScene::update() {
|
|||
mouseprev = mousepos;
|
||||
}
|
||||
|
||||
animate();
|
||||
}
|
||||
|
||||
void PythonScene::doLClick(sf::Vector2i mousepos) {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "Scene.h"
|
||||
#include "GameEngine.h"
|
||||
#include "Grid.h"
|
||||
//#include "Animation.h"
|
||||
//#include <list>
|
||||
|
||||
class PythonScene: public Scene
|
||||
{
|
||||
|
@ -13,6 +15,8 @@ class PythonScene: public Scene
|
|||
void doLClick(sf::Vector2i);
|
||||
void doRClick(sf::Vector2i);
|
||||
void doZoom(sf::Vector2i, int);
|
||||
//std::list<Animation*> animations;
|
||||
void animate();
|
||||
public:
|
||||
PythonScene(GameEngine*, std::string);
|
||||
void update() override final;
|
||||
|
|
Loading…
Reference in New Issue