yupplemayham/YuppleMayham/include/graphics/animation.h

151 lines
3.3 KiB
C++

#ifndef _H_ANIMATION_H
#define _H_ANIMATION_H
#include <memory>
#include <SDL_timer.h>
#include <vector>
#include <string>
#include <unordered_map>
#include "utility/xmlloader.h"
#include "utility/direction.h"
#include "graphics/sprite.h"
class ResourceManager;
class EventManager;
// Each entity will contain animation data,
// this data will hold:
// name of the animation,
// type of animation ie. idle animation, directional, etc.
// directory of the animation atlas containing the frames
struct Animation {
const AnimationData *data;
SpriteAtlas *spriteAtlas;
bool playing;
float FPS;
unsigned int elapsedTime = 0;
unsigned int lastFrameTick = 0;
unsigned int currentFrame;
int cycles;
Direction facingDir;
void reset() {
elapsedTime = 0;
lastFrameTick = 0;
currentFrame = 0;
};
void bind() {
spriteAtlas->bind();
}
void tick() {
Uint32 currentTime = SDL_GetTicks();
elapsedTime = currentTime - lastFrameTick;
if (elapsedTime >= 1000.0f / FPS) {
if (++currentFrame > spriteAtlas->size() - 1) {
currentFrame = 0;
cycles += 1;
}
lastFrameTick = currentTime;
}
}
void draw() {
if (playing) {
tick();
} else if (!data->directional) {
currentFrame = 0;
}
auto frame = (data->directional) ?
spriteAtlas->frame(currentFrame, facingDir) :
spriteAtlas->frame(currentFrame);
spriteAtlas->bindFrame(&frame);
spriteAtlas->draw();
}
};
struct AnimationComponent {
int entityID;
// anim-id animation
std::unordered_map<std::string, std::unique_ptr<Animation>> anims;
Animation *curAnim;
};
/*
class Animation
{
public:
Animation(const AnimationData* animData, ResourceManager* resourceManager);
std::string getPrefix() const { return prefix; }
std::string getType() const { return type; }
std::string getID() const { return prefix + "/" + type; }
void bind();
void draw();
void draw(Direction dir);
void play() { isPlaying = true; }
void stop() { isPlaying = false; }
void reset() { currentFrame = 0; lastFrameTick = 0; elapsedTime = 0; }
const bool getPlaying() const { return isPlaying; }
const bool getDirectional() const { return isDirectional; }
const int getCycles() const { return cycles; }
void setFPS(const float fps) { FPS = fps; }
private:
std::string prefix;
std::string type;
SpriteAtlas* spriteAtlas;
Uint32 elapsedTime = 0;
Uint32 lastFrameTick = 0;
float FPS;
int currentFrame;
int cycles;
bool isDirectional;
bool isPlaying;
// this ticks our frame forward according to ticks passed
void frameTick();
void singleDraw();
void directionalDraw(Direction dir);
};
*/
// We will load our animation component with every loaded animation,
// this will be the handler for every animation an entity uses
class AnimationSystem
{
public:
AnimationSystem(std::weak_ptr<ResourceManager> resourceManger, std::weak_ptr<EventManager> eventManager);
// animID is the first two elements in the ID <TYPE>/<OBJ>. The prefix
bool registerComponent(const int entityID, const std::string& animID);
void update();
void draw();
~AnimationSystem();
private:
void registerEvents(AnimationComponent *component);
std::vector<std::unique_ptr<AnimationComponent>> animComponents;
std::weak_ptr<EventManager> eventManager;
std::weak_ptr<ResourceManager> resourceManager;
};
#endif // _H_ANIMATION_H