151 lines
3.3 KiB
C++
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
|