]> git.localhorst.tv Git - l2e.git/commitdiff
added number animation
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 12 Aug 2012 19:14:13 +0000 (21:14 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 12 Aug 2012 19:14:13 +0000 (21:14 +0200)
Debug/src/battle/subdir.mk
Release/src/battle/subdir.mk
src/battle/NumberAnimation.cpp [new file with mode: 0644]
src/battle/NumberAnimation.h [new file with mode: 0644]
src/battle/states/PerformAttacks.cpp
src/battle/states/PerformAttacks.h
src/graphics/Animation.h

index 20dd9c3ac6217f13cfa7963e95559db2f031ceee..df33d4e449215a08782b92531d598ab83a76283f 100644 (file)
@@ -11,6 +11,7 @@ CPP_SRCS += \
 ../src/battle/HeroTag.cpp \
 ../src/battle/Monster.cpp \
 ../src/battle/MoveMenu.cpp \
+../src/battle/NumberAnimation.cpp \
 ../src/battle/PartyLayout.cpp \
 ../src/battle/SmallHeroTag.cpp \
 ../src/battle/TargetSelection.cpp 
@@ -23,6 +24,7 @@ OBJS += \
 ./src/battle/HeroTag.o \
 ./src/battle/Monster.o \
 ./src/battle/MoveMenu.o \
+./src/battle/NumberAnimation.o \
 ./src/battle/PartyLayout.o \
 ./src/battle/SmallHeroTag.o \
 ./src/battle/TargetSelection.o 
@@ -35,6 +37,7 @@ CPP_DEPS += \
 ./src/battle/HeroTag.d \
 ./src/battle/Monster.d \
 ./src/battle/MoveMenu.d \
+./src/battle/NumberAnimation.d \
 ./src/battle/PartyLayout.d \
 ./src/battle/SmallHeroTag.d \
 ./src/battle/TargetSelection.d 
index d25e980ec5f62a5ca3b9b7527e728f1ea64abd0f..776e8603cc4c6f057eba8e1c58a0448795b5c509 100644 (file)
@@ -11,6 +11,7 @@ CPP_SRCS += \
 ../src/battle/HeroTag.cpp \
 ../src/battle/Monster.cpp \
 ../src/battle/MoveMenu.cpp \
+../src/battle/NumberAnimation.cpp \
 ../src/battle/PartyLayout.cpp \
 ../src/battle/SmallHeroTag.cpp \
 ../src/battle/TargetSelection.cpp 
@@ -23,6 +24,7 @@ OBJS += \
 ./src/battle/HeroTag.o \
 ./src/battle/Monster.o \
 ./src/battle/MoveMenu.o \
+./src/battle/NumberAnimation.o \
 ./src/battle/PartyLayout.o \
 ./src/battle/SmallHeroTag.o \
 ./src/battle/TargetSelection.o 
@@ -35,6 +37,7 @@ CPP_DEPS += \
 ./src/battle/HeroTag.d \
 ./src/battle/Monster.d \
 ./src/battle/MoveMenu.d \
+./src/battle/NumberAnimation.d \
 ./src/battle/PartyLayout.d \
 ./src/battle/SmallHeroTag.d \
 ./src/battle/TargetSelection.d 
diff --git a/src/battle/NumberAnimation.cpp b/src/battle/NumberAnimation.cpp
new file mode 100644 (file)
index 0000000..7002f57
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * NumberAnimation.cpp
+ *
+ *  Created on: Aug 12, 2012
+ *      Author: holy
+ */
+
+#include "NumberAnimation.h"
+
+#include "../geometry/operators.h"
+#include "../geometry/Vector.h"
+
+using app::State;
+using geometry::Point;
+using geometry::Vector;
+using graphics::ComplexAnimation;
+using graphics::Sprite;
+
+namespace battle {
+
+NumberAnimation::NumberAnimation(int number, const ComplexAnimation &a, const Sprite *numbers)
+: number(number) {
+       animation[0] = a;
+       animation[1] = a;
+       animation[2] = a;
+       animation[3] = a;
+
+       animation[0].ChangeSprite(numbers);
+       animation[1].ChangeSprite(numbers);
+       animation[2].ChangeSprite(numbers);
+       animation[3].ChangeSprite(numbers);
+
+       if (number > 9999) {
+               animation[0].SetColOffset(9);
+               animation[1].SetColOffset(9);
+               animation[2].SetColOffset(9);
+               animation[3].SetColOffset(9);
+       } else {
+               animation[0].SetColOffset(number / 1000 % 10);
+               animation[1].SetColOffset(number / 100 % 10);
+               animation[2].SetColOffset(number / 10 % 10);
+               animation[3].SetColOffset(number % 10);
+       }
+}
+
+void NumberAnimation::Start(State &s) {
+       if (number > 999) {
+               animation[0].Start(s);
+       } else if (number > 99) {
+               animation[1].Start(s);
+       } else if (number > 9) {
+               animation[2].Start(s);
+       } else {
+               animation[3].Start(s);
+       }
+}
+
+bool NumberAnimation::Running() const {
+       return animation[0].Running() || animation[1].Running() || animation[2].Running() || animation[3].Running();
+}
+
+void NumberAnimation::CheckTimers(State &s) {
+       if (animation[0].Running() && animation[0].Frame() == 1) {
+               animation[1].Start(s);
+       } else if (animation[1].Running() && animation[1].Frame() == 1) {
+               animation[2].Start(s);
+       } else if (animation[2].Running() && animation[2].Frame() == 1) {
+               animation[3].Start(s);
+       }
+}
+
+
+int NumberAnimation::Width() const {
+       if (number < 10) {
+               return animation[0].GetSprite()->Width();
+       } else if (number < 100) {
+               return 2 * animation[0].GetSprite()->Width();
+       } else if (number < 1000) {
+               return 3 * animation[0].GetSprite()->Width();
+       } else {
+               return 4 * animation[0].GetSprite()->Width();
+       }
+}
+
+int NumberAnimation::Height() const {
+       return animation[0].GetSprite()->Height();
+}
+
+void NumberAnimation::Draw(SDL_Surface *dest, const Point<int> &positionIn) const {
+       Point<int> position(positionIn);
+       Vector<int> step(animation[0].GetSprite()->Width(), 0);
+       if (number > 999) {
+               if (animation[0].Running()) {
+                       animation[0].Draw(dest, position);
+               }
+               position += step;
+       }
+       if (number > 99) {
+               if (animation[1].Running() || animation[0].Running()) {
+                       animation[1].Draw(dest, position);
+               }
+               position += step;
+       }
+       if (number > 9) {
+               if (animation[2].Running() || animation[1].Running() || animation[0].Running()) {
+                       animation[2].Draw(dest, position);
+               }
+               position += step;
+       }
+       if (animation[3].Running() || animation[2].Running() || animation[1].Running() || animation[0].Running()) {
+               animation[3].Draw(dest, position);
+       }
+}
+
+}
diff --git a/src/battle/NumberAnimation.h b/src/battle/NumberAnimation.h
new file mode 100644 (file)
index 0000000..2c96b5e
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * NumberAnimation.h
+ *
+ *  Created on: Aug 12, 2012
+ *      Author: holy
+ */
+
+#ifndef BATTLE_NUMBERANIMATION_H_
+#define BATTLE_NUMBERANIMATION_H_
+
+#include "../graphics/ComplexAnimation.h"
+
+#include "../geometry/Point.h"
+
+namespace app {
+       class Application;
+       class State;
+}
+
+namespace battle {
+
+class NumberAnimation {
+
+public:
+       NumberAnimation() : number(-1) { }
+       NumberAnimation(int number, const graphics::ComplexAnimation &prototype, const graphics::Sprite *numbers);
+
+public:
+       void Start(app::State &);
+       bool Running() const;
+       void CheckTimers(app::State &);
+
+       int Width() const;
+       int Height() const;
+
+       void Draw(SDL_Surface *dest, const geometry::Point<int> &position) const;
+
+private:
+       int number;
+       graphics::ComplexAnimation animation[4];
+
+};
+
+}
+
+#endif /* BATTLE_NUMBERANIMATION_H_ */
index 4f7a427c6a404a5fbac1ecc3f29de5c1bba936b7..b5cd9bebec80754ee019001b972616b557829e34 100644 (file)
@@ -27,12 +27,15 @@ using app::Application;
 using app::Input;
 using geometry::Point;
 using geometry::Vector;
+using std::vector;
 
 namespace battle {
 
 void PerformAttacks::EnterState(Application &c, SDL_Surface *screen) {
        ctrl = &c;
        battle->WriteOrder(order);
+       numberAnimation.reserve(battle->MaxMonsters() > battle->NumHeroes() + 1 ? battle->MaxMonsters() : battle->NumHeroes() + 1);
+       numberPosition.reserve(numberAnimation.size());
 }
 
 void PerformAttacks::ExitState(Application &c, SDL_Surface *screen) {
@@ -54,23 +57,11 @@ void PerformAttacks::Resize(int width, int height) {
 
 
 void PerformAttacks::HandleEvents(const Input &input) {
-       if (titleBarTimer.Running() || (moveAnimation && moveAnimation->Running())) return;
-
-       if (moveAnimation) moveAnimation->Stop();
-       titleBarTimer.Clear();
-
-       ++cursor;
-
-       while (cursor < int(order.size())) {
-               if (order[cursor].isMonster) {
-                       if (battle->MonsterAt(order[cursor].index).Health() > 0) break;
-               } else {
-                       if (battle->HeroAt(order[cursor].index).Health() > 0) break;
-               }
-               ++cursor;
-       }
-
-       if (cursor >= int(order.size())) {
+       CheckNumberAnimation();
+       if (HasAnimationsRunning()) return;
+       ResetAnimation();
+       AdvanceCursor();
+       if (Finished()) {
                battle->ClearAllAttacks();
                ctrl->PopState();
                return;
@@ -88,6 +79,14 @@ void PerformAttacks::HandleEvents(const Input &input) {
                        case AttackChoice::SWORD:
                                titleBarText = hero.HasWeapon() ? hero.Weapon()->Name() : "Melee attack!";
                                moveAnimation = hero.AttackAnimation();
+                               numberAnimation.push_back(NumberAnimation(15, battle->Res().numberAnimationPrototype, battle->Res().bigNumberSprite));
+                               if (ac.Selection().TargetsEnemies()) {
+                                       numberPosition.push_back(
+                                                       battle->MonsterPositions()[ac.Selection().SingleSelection()]);
+                               } else {
+                                       numberPosition.push_back(
+                                                       battle->HeroesPositions()[ac.Selection().SingleSelection()]);
+                               }
                                break;
                        case AttackChoice::MAGIC:
                                titleBarText = ac.GetSpell()->Name();
@@ -118,10 +117,51 @@ void PerformAttacks::HandleEvents(const Input &input) {
                }
        }
 
-       titleBarTimer = GraphicsTimers().StartCountdown(1500);
+       if (titleBarText) titleBarTimer = GraphicsTimers().StartCountdown(1500);
        if (moveAnimation) moveAnimation->Start(*this);
 }
 
+void PerformAttacks::CheckNumberAnimation() {
+       if (moveAnimation && moveAnimation->Running()) return;
+       if (!moveAnimation || moveAnimation->JustFinished()) {
+               for (vector<NumberAnimation>::iterator i(numberAnimation.begin()), end(numberAnimation.end()); i != end; ++i) {
+                       i->Start(*this);
+               }
+       } else {
+               for (vector<NumberAnimation>::iterator i(numberAnimation.begin()), end(numberAnimation.end()); i != end; ++i) {
+                       i->CheckTimers(*this);
+               }
+       }
+}
+
+bool PerformAttacks::HasAnimationsRunning() const {
+       if (titleBarTimer.Running()) return true;
+       if (moveAnimation && moveAnimation->Running()) return true;
+       for (vector<NumberAnimation>::const_iterator i(numberAnimation.begin()), end(numberAnimation.end()); i != end; ++i) {
+               if (i->Running()) return true;
+       }
+       return false;
+}
+
+void PerformAttacks::ResetAnimation() {
+       if (moveAnimation) moveAnimation->Stop();
+       titleBarTimer.Clear();
+       numberAnimation.clear();
+       numberPosition.clear();
+}
+
+void PerformAttacks::AdvanceCursor() {
+       ++cursor;
+       while (cursor < int(order.size())) {
+               if (order[cursor].isMonster) {
+                       if (battle->MonsterAt(order[cursor].index).Health() > 0) break;
+               } else {
+                       if (battle->HeroAt(order[cursor].index).Health() > 0) break;
+               }
+               ++cursor;
+       }
+}
+
 
 void PerformAttacks::UpdateWorld(float deltaT) {
 
@@ -134,6 +174,7 @@ void PerformAttacks::Render(SDL_Surface *screen) {
        battle->RenderHeroes(screen, offset);
        battle->RenderSmallHeroTags(screen, offset);
        RenderTitleBar(screen, offset);
+       RenderNumbers(screen, offset);
 }
 
 void PerformAttacks::RenderTitleBar(SDL_Surface *screen, const Vector<int> &offset) {
@@ -148,4 +189,13 @@ void PerformAttacks::RenderTitleBar(SDL_Surface *screen, const Vector<int> &offs
        battle->Res().titleFont->DrawString(titleBarText, screen, textPosition + offset);
 }
 
+void PerformAttacks::RenderNumbers(SDL_Surface *screen, const Vector<int> &offset) {
+       for (vector<NumberAnimation>::size_type i(0), end(numberAnimation.size()); i < end; ++i) {
+               if (numberAnimation[i].Running()) {
+                       Vector<int> align(numberAnimation[i].Width() / -2, numberAnimation[i].Height() * -3 / 4);
+                       numberAnimation[i].Draw(screen, numberPosition[i] + align + offset);
+               }
+       }
+}
+
 }
index e0d3df821a0a66f944884048eef1f6c2fbd0d43c..a5f3247b404a7fd2bf64fd0dd495453c18843d7d 100644 (file)
 #include "../../app/State.h"
 
 #include "../BattleState.h"
+#include "../NumberAnimation.h"
 #include "../../geometry/Vector.h"
+#include "../../graphics/ComplexAnimation.h"
 
 #include <vector>
 
-namespace graphics { class Animation; }
-
 namespace battle {
 
 class PerformAttacks
@@ -38,8 +38,16 @@ public:
        virtual void UpdateWorld(float deltaT);
        virtual void Render(SDL_Surface *);
 
+private:
+       void CheckNumberAnimation();
+       bool HasAnimationsRunning() const;
+       void ResetAnimation();
+       void AdvanceCursor();
+       bool Finished() const { return cursor >= int(order.size()); }
+
 private:
        void RenderTitleBar(SDL_Surface *screen, const geometry::Vector<int> &offset);
+       void RenderNumbers(SDL_Surface *screen, const geometry::Vector<int> &offset);
 
 private:
        app::Application *ctrl;
@@ -48,6 +56,8 @@ private:
        const char *titleBarText;
        app::Timer<Uint32> titleBarTimer;
        std::vector<BattleState::Order> order;
+       std::vector<NumberAnimation> numberAnimation;
+       std::vector<geometry::Point<int> > numberPosition;
        int cursor;
 
 };
index 524912d5743029a1b2ca8cabbc586949267df373..0c6ae288b4a5e04220f764d9c5ba6b4ee05597c4 100644 (file)
@@ -42,6 +42,9 @@ public:
        bool Running() const {
                return timer.Running() && (repeat || timer.Iteration() < NumFrames());
        }
+       bool JustFinished() const {
+               return timer.JustHit() && timer.Iteration() == NumFrames();
+       }
 
        const app::Timer<Uint32> &GetTimer() { return timer; }