]> git.localhorst.tv Git - l2e.git/blob - src/graphics/Animation.h
be92ca129fec5c5ad2438abf912063c5a36fcbe6
[l2e.git] / src / graphics / Animation.h
1 /*
2  *  Animation.h
3  *
4  *  Created on: Aug 11, 2012
5  *      Author: holy
6  */
7
8 #ifndef GRAPHICS_ANIMATION_H_
9 #define GRAPHICS_ANIMATION_H_
10
11 #include "Sprite.h"
12 #include "../app/Application.h"
13 #include "../app/State.h"
14 #include "../app/Timer.h"
15 #include "../loader/fwd.h"
16 #include "../geometry/Vector.h"
17
18 #include <memory>
19 #include <SDL.h>
20
21 namespace graphics {
22
23 class Animation {
24
25 public:
26         static const int TYPE_ID = 401;
27
28 public:
29         Animation()
30         : sprite(0), frameTime(0), repeat(false) { }
31         Animation(const Sprite *sprite, int frameTime, bool repeat = false)
32         : sprite(sprite), frameTime(frameTime), repeat(repeat) { }
33         virtual ~Animation() { };
34
35 public:
36         const Sprite *GetSprite() const { return sprite; }
37         int FrameTime() const { return frameTime; }
38         bool Repeat() const { return repeat; }
39
40 public:
41         void SetSprite(const Sprite *s) { sprite = s; }
42         void SetFrameTime(int t) { frameTime = t; }
43         void SetRepeat(bool r) { repeat = r; }
44
45 public:
46         virtual int NumFrames() const = 0;
47         virtual int Col(int frame) const = 0;
48         virtual int Row(int frame) const = 0;
49         virtual geometry::Vector<int> Offset(int frame) const { return geometry::Vector<int>(); }
50
51         static void CreateTypeDescription();
52
53 protected:
54         static void AddFields(loader::TypeDescription &, const Animation &, std::ptrdiff_t offset);
55
56 private:
57         const Sprite *sprite;
58         int frameTime;
59         bool repeat;
60
61 };
62
63
64 class AnimationRunner {
65
66 public:
67         explicit AnimationRunner(const Animation *a = 0, int colOffset = 0, int rowOffset = 0)
68         : animation(a), sprite(0), frameShift(0), colOffset(colOffset), rowOffset(rowOffset) { }
69
70 public:
71         bool Valid() const { return animation; }
72         void Clear() { animation = 0; timer = app::Timer<Uint32>(); }
73
74         void Start(app::State &ctrl) {
75                 timer = ctrl.GraphicsTimers().StartInterval(animation->FrameTime());
76         }
77         void Start(app::Application &ctrl) {
78                 timer = ctrl.GlobalTimers().StartInterval(animation->FrameTime());
79         }
80         void Stop() {
81                 timer = app::Timer<Uint32>();
82         }
83         bool Started() const {
84                 return timer.Started();
85         }
86         bool Running() const {
87                 return timer.Running() && (animation->Repeat() || timer.Iteration() < animation->NumFrames());
88         }
89         bool Finished() const {
90                 return Started() && !Running();
91         }
92         bool JustFinished() const {
93                 return timer.JustHit() && timer.Iteration() == animation->NumFrames();
94         }
95
96         const app::Timer<Uint32> &GetTimer() { return timer; }
97
98         void SetFrameShift(int offset) { frameShift = offset; }
99         int FrameShift() const { return frameShift; }
100         void SetColOffset(int offset) { colOffset = offset; }
101         int ColOffset() const { return colOffset; }
102         void SetRowOffset(int offset) { rowOffset = offset; }
103         int RowOffset() const { return rowOffset; }
104
105         void ChangeAnimation(const Animation *a) { animation = a; }
106         const Animation *GetAnimation() const { return animation; }
107
108         void ChangeSprite(const Sprite *s) { sprite = s; }
109         const Sprite *GetSprite() const { return sprite ? sprite : animation->GetSprite(); }
110
111         void Draw(SDL_Surface *dest, geometry::Vector<int> position) const {
112                 GetSprite()->Draw(dest, position + animation->Offset(Frame()), animation->Col(Frame()) + ColOffset(), animation->Row(Frame()) + RowOffset());
113         }
114         void DrawTopRight(SDL_Surface *dest, geometry::Vector<int> position) const {
115                 geometry::Vector<int> offset(-GetSprite()->Width(), 0);
116                 Draw(dest, position + offset);
117         }
118         void DrawCenter(SDL_Surface *dest, geometry::Vector<int> position) const {
119                 Draw(dest, position - (GetSprite()->Size() / 2));
120         }
121         void DrawCenterBottom(SDL_Surface *dest, geometry::Vector<int> position) const {
122                 geometry::Vector<int> offset(-GetSprite()->Width() / 2, -GetSprite()->Height());
123                 Draw(dest, position + offset);
124         }
125
126         int Frame() const { return Running() ? ((timer.Iteration() + frameShift) % animation->NumFrames()) : 0; }
127
128 private:
129         const Animation *animation;
130         const graphics::Sprite *sprite;
131         app::Timer<Uint32> timer;
132         int frameShift;
133         int colOffset;
134         int rowOffset;
135
136 };
137
138 }
139
140 #endif /* GRAPHICS_SIMPLEANIMATION_H_ */