]> git.localhorst.tv Git - l2e.git/blobdiff - src/graphics/Animation.cpp
renamed namespace geometry -> math
[l2e.git] / src / graphics / Animation.cpp
index caffb50c653a814ed9d1512e0c1591531d2b5095..602d7ef5d7613ada5118239b3ebf870e381633fc 100644 (file)
@@ -1,27 +1,94 @@
-/*
- * Animation.cpp
- *
- *  Created on: Sep 5, 2012
- *      Author: holy
- */
-
 #include "Animation.h"
 
+#include "Sprite.h"
+#include "../app/Application.h"
+#include "../app/State.h"
+#include "../loader/Interpreter.h"
 #include "../loader/TypeDescription.h"
 
+#include <cassert>
+
 using loader::FieldDescription;
+using loader::Interpreter;
 using loader::TypeDescription;
 
 namespace graphics {
 
-void AddFields(TypeDescription &td, const Animation &a, std::ptrdiff_t offset) {
-       int boolId(TypeDescription::GetTypeId("Boolean"));
-       int numberId(TypeDescription::GetTypeId("Number"));
-       int spriteId(TypeDescription::GetTypeId("Sprite"));
+void Animation::CreateTypeDescription() {
+       TypeDescription &td(TypeDescription::Create(TYPE_ID, "Animation"));
+       td.SetDescription("Abstract base type for animations.");
+       td.SetSize(sizeof(Animation));
+}
+
+void Animation::AddFields(TypeDescription &td, const Animation &a, std::ptrdiff_t offset) {
+       td.AddField("sprite", FieldDescription(((char *)&a.sprite) - ((char *)&a) - offset, Sprite::TYPE_ID).SetReferenced().SetDescription("the sprite used for cutting out frames"));
+       td.AddField("frametime", FieldDescription(((char *)&a.frameTime) - ((char *)&a) - offset, Interpreter::NUMBER_ID).SetDescription("duration of a frame in miliseconds"));
+       td.AddField("repeat", FieldDescription(((char *)&a.repeat) - ((char *)&a) - offset, Interpreter::BOOLEAN_ID).SetDescription("whether the animation should start over at the beginning after reaching the last frame"));
+}
+
+
+void AnimationRunner::Start(app::State &ctrl) {
+       assert(animation);
+       timer = ctrl.GraphicsTimers().StartInterval(animation->FrameTime());
+}
+
+void AnimationRunner::Start(app::Application &ctrl) {
+       assert(animation);
+       timer = ctrl.GlobalTimers().StartInterval(animation->FrameTime());
+}
+
+void AnimationRunner::Stop() {
+       timer = app::Timer<Uint32>();
+}
+
+bool AnimationRunner::Started() const {
+       return timer.Started();
+}
+
+bool AnimationRunner::Running() const {
+       return animation
+                       && timer.Running()
+                       && (animation->Repeat()
+                                       || timer.Iteration() < animation->NumFrames());
+}
+
+bool AnimationRunner::Finished() const {
+       return Started() && !Running();
+}
+
+bool AnimationRunner::JustFinished() const {
+       return animation
+                       && timer.JustHit()
+                       && timer.Iteration() == animation->NumFrames();
+}
+
+
+void AnimationRunner::Draw(SDL_Surface *dest, math::Vector<int> position) const {
+       GetSprite()->Draw(dest,
+                       position + animation->Offset(Frame()),
+                       animation->Col(Frame()) + ColOffset(),
+                       animation->Row(Frame()) + RowOffset());
+}
 
-       td.AddField("sprite", FieldDescription(((char *)&a.sprite) - ((char *)&a) - offset, spriteId, true));
-       td.AddField("frametime", FieldDescription(((char *)&a.frameTime) - ((char *)&a) - offset, numberId, false));
-       td.AddField("repeat", FieldDescription(((char *)&a.repeat) - ((char *)&a) - offset, boolId, false));
+void AnimationRunner::DrawTopRight(SDL_Surface *dest, math::Vector<int> position) const {
+       math::Vector<int> offset(-GetSprite()->Width(), 0);
+       Draw(dest, position + offset);
 }
 
+void AnimationRunner::DrawCenter(SDL_Surface *dest, math::Vector<int> position) const {
+       Draw(dest, position - (GetSprite()->Size() / 2));
+}
+
+void AnimationRunner::DrawCenterBottom(SDL_Surface *dest, math::Vector<int> position) const {
+       math::Vector<int> offset(-GetSprite()->Width() / 2, -GetSprite()->Height());
+       Draw(dest, position + offset);
+}
+
+int AnimationRunner::Frame() const {
+       return Running()
+                       ? ((timer.Iteration() + frameShift) % animation->NumFrames())
+                       : 0;
+}
+
+
 }