载入中...
搜索中...
未找到
SpriteAnim.cpp
浏览该文件的文档.
2
6#include "common/Exception.h"
7#include "graphics/Quad.h"
8
9#include <cmath>
10
11namespace eve::animation {
12
13SpriteAnim::SpriteAnim() = default;
14
16 if (owner_) owner_->unregisterSpriteAnim(this);
17}
18
19void SpriteAnim::setSheet(SpriteSheet *sheet) { sheet_ = sheet; }
20
22 if (!clip) throw Exception("SpriteAnim.play: clip is null");
23 clip_ = clip;
24 time_ = 0.f;
25 playing_ = true;
26 paused_ = false;
27 finished_ = false;
28 refreshFrame();
29 syncBoundQuad();
30}
31
33 playing_ = false;
34 paused_ = false;
35 finished_ = false;
36 time_ = 0.f;
37 clipFrame_ = -1;
38}
39
41 if (playing_) paused_ = true;
42}
43
45 if (playing_ && paused_) paused_ = false;
46}
47
48void SpriteAnim::setSpeed(float speed) {
49 if (speed < 0.f) throw Exception("SpriteAnim.setSpeed: speed must be >= 0");
50 speed_ = speed;
51}
52
53void SpriteAnim::setTime(float seconds) {
54 if (seconds < 0.f) throw Exception("SpriteAnim.setTime: time must be >= 0");
55 time_ = seconds;
56 refreshFrame();
57 syncBoundQuad();
58}
59
60void SpriteAnim::setLoop(bool loop) {
61 loopOverride_ = true;
62 loopValue_ = loop;
63}
64
65bool SpriteAnim::getLoop() const {
66 return loopOverride_ ? loopValue_ : (clip_ && clip_->getLoop());
67}
68
70 if (!clip_ || clipFrame_ < 0) return -1;
71 return clip_->getSheetFrame(clipFrame_);
72}
73
75 boundQuad_ = quad;
76 syncBoundQuad();
77}
78
79void SpriteAnim::unbindQuad() { boundQuad_ = nullptr; }
80
82 if (!quad) throw Exception("SpriteAnim.applyToQuad: quad is null");
83 if (!sheet_) throw Exception("SpriteAnim.applyToQuad: sheet is null");
84 int sf = getSheetFrame();
85 if (sf < 0) throw Exception("SpriteAnim.applyToQuad: no current frame");
86 sheet_->applyToQuad(quad, sf);
87}
88
89void SpriteAnim::refreshFrame() {
90 if (!clip_ || clip_->getFrameCount() == 0) {
91 clipFrame_ = -1;
92 return;
93 }
94
95 const float dur = clip_->getDuration();
96 if (dur <= 0.f) {
97 clipFrame_ = 0;
98 return;
99 }
100
101 const bool loop = getLoop();
102 float local = time_;
103 if (loop) {
104 local = std::fmod(local, dur);
105 if (local < 0.f) local += dur;
106 } else if (local >= dur) {
107 clipFrame_ = clip_->getFrameCount() - 1;
108 return;
109 } else if (local < 0.f) {
110 local = 0.f;
111 }
112
113 float acc = 0.f;
114 for (int i = 0; i < clip_->getFrameCount(); ++i) {
115 acc += clip_->getFrameDuration(i);
116 if (local < acc || i == clip_->getFrameCount() - 1) {
117 clipFrame_ = i;
118 return;
119 }
120 }
121 clipFrame_ = clip_->getFrameCount() - 1;
122}
123
124void SpriteAnim::syncBoundQuad() {
125 if (!boundQuad_ || !sheet_) return;
126 int sf = getSheetFrame();
127 if (sf < 0) return;
128 sheet_->applyToQuad(boundQuad_, sf);
129}
130
131bool SpriteAnim::update(float dt) {
132 if (dt < 0.f) throw Exception("SpriteAnim.update: dt must be >= 0");
133 if (!playing_ || paused_ || !clip_) return playing_ || paused_;
134
135 time_ += dt * speed_;
136 const float dur = clip_->getDuration();
137 const bool loop = getLoop();
138
139 if (dur <= 0.f) {
140 refreshFrame();
141 syncBoundQuad();
142 return true;
143 }
144
145 if (!loop && time_ >= dur) {
146 time_ = dur;
147 finished_ = true;
148 playing_ = false;
149 refreshFrame();
150 syncBoundQuad();
151 return false;
152 }
153
154 refreshFrame();
155 syncBoundQuad();
156 return true;
157}
158
159} // namespace eve::animation
void bindQuad(graphics::Quad *quad)
Keep this Quad's viewport updated each update/play.
bool update(float dt)
Advance playback. Returns true while still active (playing or paused). Auto-applies to boundQuad when...
void setTime(float seconds)
void play(SpriteClip *clip)
void setSpeed(float speed)
void setSheet(SpriteSheet *sheet)
Optional sheet used by applyToQuad / bindQuad.
void applyToQuad(graphics::Quad *quad) const
Write current sheet frame into quad (requires sheet).
int getSheetFrame() const
Sheet frame index for the current cell, or -1.
Named 2D frame sequence referencing SpriteSheet frame indices. Script type: SpriteClip.
Definition SpriteClip.h:14
int getSheetFrame(int index) const
float getFrameDuration(int index) const
Sprite-sheet / texture-atlas frame table (pixel rects).
Definition SpriteSheet.h:20
void applyToQuad(graphics::Quad *quad, int frameIndex) const
Write pixel viewport into an existing Quad (does not allocate).
Pixel-space sub-rectangle of a Texture (atlas cell / sprite frame). UV conversion uses the texture's ...
Definition Quad.h:9