From: Daniel Karbach Date: Sun, 12 Aug 2012 00:15:03 +0000 (+0200) Subject: added complex attack and spell animations X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=854e5229c3f30bf88aa08d7f0aff56a1411c3367;p=l2e.git added complex attack and spell animations --- diff --git a/src/battle/BattleState.cpp b/src/battle/BattleState.cpp index 1b44010..03cbb21 100644 --- a/src/battle/BattleState.cpp +++ b/src/battle/BattleState.cpp @@ -266,8 +266,10 @@ void BattleState::RenderMonsters(SDL_Surface *screen, const Vector &offset) void BattleState::RenderHeroes(SDL_Surface *screen, const Vector &offset) { for (int i(0); i < numHeroes; ++i) { - if (HeroAnimationAt(i).Running()) { - HeroAnimationAt(i).DrawCenterBottom(screen, heroesPositions[i] + offset); + if (heroes[i].AttackAnimation() && heroes[i].AttackAnimation()->Running()) { + heroes[i].AttackAnimation()->DrawCenterBottom(screen, heroesPositions[i] + offset); + } else if (heroes[i].SpellAnimation() && heroes[i].SpellAnimation()->Running()) { + heroes[i].SpellAnimation()->DrawCenterBottom(screen, heroesPositions[i] + offset); } else { int row(heroes[i].Health() > 0 ? 0 : 2); heroes[i].Sprite()->DrawCenterBottom(screen, heroesPositions[i] + offset, 1, row); diff --git a/src/battle/BattleState.h b/src/battle/BattleState.h index 77e2b5d..40dd51d 100644 --- a/src/battle/BattleState.h +++ b/src/battle/BattleState.h @@ -19,8 +19,8 @@ #include "../app/State.h" #include "../geometry/Point.h" #include "../geometry/Vector.h" +#include "../graphics/Animation.h" #include "../graphics/Menu.h" -#include "../graphics/SimpleAnimation.h" #include #include @@ -97,9 +97,6 @@ public: Monster &MonsterAt(int index) { return monsters[index]; } const Monster &MonsterAt(int index) const { return monsters[index]; } - graphics::SimpleAnimation &HeroAnimationAt(int index) { return heroAnimations[index]; } - const graphics::SimpleAnimation &HeroAnimationAt(int index) const { return heroAnimations[index]; } - const HeroTag &HeroTagAt(int index) const { return heroTags[index]; } const geometry::Point &HeroTagPositionAt(int index) const { return heroTagPositions[index]; } @@ -153,7 +150,6 @@ private: std::vector > heroesPositions; std::vector monsters; Hero heroes[4]; - graphics::SimpleAnimation heroAnimations[4]; graphics::Menu spellMenus[4]; graphics::Menu itemMenu; graphics::Menu ikariMenus[4]; diff --git a/src/battle/Hero.cpp b/src/battle/Hero.cpp index 4bcc6d3..ff41113 100644 --- a/src/battle/Hero.cpp +++ b/src/battle/Hero.cpp @@ -20,6 +20,9 @@ Hero::Hero() , ring(0) , jewel(0) +, attackAnimation(0) +, spellAnimation(0) + , maxHealth(0) , health(0) , maxMana(0) diff --git a/src/battle/Hero.h b/src/battle/Hero.h index 11f1e33..97a21c2 100644 --- a/src/battle/Hero.h +++ b/src/battle/Hero.h @@ -15,7 +15,10 @@ namespace common { class Item; class Spell; } -namespace graphics { class Sprite; } +namespace graphics { + class Animation; + class Sprite; +} namespace battle { @@ -66,10 +69,10 @@ public: bool HasRing() const { return ring; } bool HasJewel() const { return jewel; } - int AttackFrames() const { return attackFrames; } - int AttackFrameTime() const { return attackFrameTime; } - int SpellFrames() const { return spellFrames; } - int SpellFrameTime() const { return spellFrameTime; } + graphics::Animation *AttackAnimation() { return attackAnimation; } + const graphics::Animation *AttackAnimation() const { return attackAnimation; } + graphics::Animation *SpellAnimation() { return spellAnimation; } + const graphics::Animation *SpellAnimation() const { return spellAnimation; } // temporary setters until loader is implemented public: @@ -92,8 +95,8 @@ public: void AddSpell(const common::Spell *s) { spells.push_back(s); } - void SetAttackFrames(int num, int time) { attackFrames = num; attackFrameTime = time; } - void SetSpellFrames(int num, int time) { spellFrames = num; spellFrameTime = time; } + void SetAttackAnimation(graphics::Animation *a) { attackAnimation = a; } + void SetSpellAnimation(graphics::Animation *a) { spellAnimation = a; } private: const char *name; @@ -106,14 +109,12 @@ private: const common::Item *ring; const common::Item *jewel; + graphics::Animation *attackAnimation; + graphics::Animation *spellAnimation; + // TODO: vector does not seem to be a good choice std::vector spells; - int attackFrames; - int attackFrameTime; - int spellFrames; - int spellFrameTime; - Uint16 maxHealth, health; Uint16 maxMana, mana; diff --git a/src/battle/states/PerformAttacks.cpp b/src/battle/states/PerformAttacks.cpp index c34e114..93a09ef 100644 --- a/src/battle/states/PerformAttacks.cpp +++ b/src/battle/states/PerformAttacks.cpp @@ -17,9 +17,9 @@ #include "../../common/Spell.h" #include "../../geometry/operators.h" #include "../../geometry/Point.h" +#include "../../graphics/Animation.h" #include "../../graphics/Font.h" #include "../../graphics/Frame.h" -#include "../../graphics/SimpleAnimation.h" #include @@ -27,13 +27,11 @@ using app::Application; using app::Input; using geometry::Point; using geometry::Vector; -using graphics::SimpleAnimation; namespace battle { void PerformAttacks::EnterState(Application &c, SDL_Surface *screen) { ctrl = &c; - // TODO: push battle animation if enemy is faster } void PerformAttacks::ExitState(Application &c, SDL_Surface *screen) { @@ -69,7 +67,12 @@ void PerformAttacks::HandleEvents(const Input &input) { } } else { if (cursor == 0) { - battle->HeroAnimationAt(battle->NumHeroes() - 1).Stop(); + if (battle->HeroAt(battle->NumHeroes() - 1).AttackAnimation()) { + battle->HeroAt(battle->NumHeroes() - 1).AttackAnimation()->Stop(); + } + if (battle->HeroAt(battle->NumHeroes() - 1).SpellAnimation()) { + battle->HeroAt(battle->NumHeroes() - 1).SpellAnimation()->Stop(); + } } titleBarText = battle->MonsterAt(cursor).Name(); } @@ -80,31 +83,27 @@ void PerformAttacks::HandleEvents(const Input &input) { switch (ac.GetType()) { case AttackChoice::SWORD: - battle->HeroAnimationAt(cursor) = SimpleAnimation( - battle->HeroAt(cursor).Sprite(), - battle->HeroAt(cursor).AttackFrameTime(), - battle->HeroAt(cursor).AttackFrames(), 2); + if (battle->HeroAt(cursor).AttackAnimation()) { + battle->HeroAt(cursor).AttackAnimation()->Start(*this); + } break; case AttackChoice::MAGIC: - battle->HeroAnimationAt(cursor) = SimpleAnimation( - battle->HeroAt(cursor).Sprite(), - battle->HeroAt(cursor).SpellFrameTime(), - battle->HeroAt(cursor).SpellFrames(), 3); + if (battle->HeroAt(cursor).SpellAnimation()) { + battle->HeroAt(cursor).SpellAnimation()->Start(*this); + } break; case AttackChoice::DEFEND: break; case AttackChoice::IKARI: if (ac.GetItem()->HasIkari()) { if (ac.GetItem()->GetIkari()->IsMagical()) { - battle->HeroAnimationAt(cursor) = SimpleAnimation( - battle->HeroAt(cursor).Sprite(), - battle->HeroAt(cursor).SpellFrameTime(), - battle->HeroAt(cursor).SpellFrames(), 3); + if (battle->HeroAt(cursor).SpellAnimation()) { + battle->HeroAt(cursor).SpellAnimation()->Start(*this); + } } else { - battle->HeroAnimationAt(cursor) = SimpleAnimation( - battle->HeroAt(cursor).Sprite(), - battle->HeroAt(cursor).AttackFrameTime(), - battle->HeroAt(cursor).AttackFrames(), 2); + if (battle->HeroAt(cursor).AttackAnimation()) { + battle->HeroAt(cursor).AttackAnimation()->Start(*this); + } } } break; @@ -113,7 +112,6 @@ void PerformAttacks::HandleEvents(const Input &input) { case AttackChoice::UNDECIDED: break; } - battle->HeroAnimationAt(cursor).Start(*this); ++cursor; if (cursor == battle->NumHeroes()) { @@ -122,7 +120,12 @@ void PerformAttacks::HandleEvents(const Input &input) { } } else { if (cursor > 0) { - battle->HeroAnimationAt(cursor - 1).Stop(); + if (battle->HeroAt(cursor - 1).AttackAnimation()) { + battle->HeroAt(cursor - 1).AttackAnimation()->Stop(); + } + if (battle->HeroAt(cursor - 1).SpellAnimation()) { + battle->HeroAt(cursor - 1).SpellAnimation()->Stop(); + } } switch (ac.GetType()) { case AttackChoice::SWORD: diff --git a/src/main.cpp b/src/main.cpp index 730c5aa..aff39b5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,8 @@ #include "common/Item.h" #include "common/Spell.h" #include "geometry/Point.h" +#include "geometry/Vector.h" +#include "graphics/ComplexAnimation.h" #include "graphics/Font.h" #include "graphics/Frame.h" #include "graphics/Gauge.h" @@ -42,6 +44,8 @@ using common::Inventory; using common::Item; using common::Spell; using geometry::Point; +using geometry::Vector; +using graphics::ComplexAnimation; using graphics::Font; using graphics::Frame; using graphics::Gauge; @@ -97,8 +101,19 @@ int main(int argc, char **argv) { maxim.SetMaxMana(20); maxim.SetMana(20); maxim.SetIP(0); - maxim.SetAttackFrames(3, 125); - maxim.SetSpellFrames(2, 125); + ComplexAnimation maximAttackAnimation(&maximSprite, 30); + maximAttackAnimation.AddFrames(2, 0, Vector(), 2); + maximAttackAnimation.AddFrames(2, 0, Vector(4, 0), 2); + maximAttackAnimation.AddFrame(2, 1, Vector(4, 0)); + maximAttackAnimation.AddFrames(2, 1, Vector(-2, 0), 2); + maximAttackAnimation.AddFrame(2, 1, Vector(-8, 0)); + maximAttackAnimation.AddFrames(2, 2, Vector(-8, 0), 2); + maximAttackAnimation.AddFrame(2, 2, Vector(-4, 0)); + maxim.SetAttackAnimation(&maximAttackAnimation); + ComplexAnimation maximSpellAnimation(&maximSprite, 150); + maximSpellAnimation.AddFrames(3, 0, Vector(), 2); + maximSpellAnimation.AddFrame(3, 1); + maxim.SetSpellAnimation(&maximSpellAnimation); SDL_Surface *selanImg(IMG_Load("test-data/selan.png")); Sprite selanSprite(selanImg, 64, 64); @@ -111,8 +126,24 @@ int main(int argc, char **argv) { selan.SetMaxMana(23); selan.SetMana(23); selan.SetIP(1); - selan.SetAttackFrames(3, 125); - selan.SetSpellFrames(4, 125); + ComplexAnimation selanAttackAnimation(&selanSprite, 30); + selanAttackAnimation.AddFrames(1, 0, Vector(4, 0), 2); + selanAttackAnimation.AddFrame(1, 0, Vector(8, 2)); + selanAttackAnimation.AddFrame(2, 0, Vector(10, 4)); + selanAttackAnimation.AddFrame(2, 0, Vector(14, 4)); + selanAttackAnimation.AddFrames(2, 0, Vector(12, 2), 3); + selanAttackAnimation.AddFrames(2, 1, Vector(14, 2), 2); + selanAttackAnimation.AddFrame(2, 1, Vector(2, 0)); + selanAttackAnimation.AddFrame(2, 2, Vector(-2, -4)); + selanAttackAnimation.AddFrame(2, 2, Vector(-8, -8)); + selanAttackAnimation.AddFrame(2, 2); + selan.SetAttackAnimation(&selanAttackAnimation); + ComplexAnimation selanSpellAnimation(&selanSprite, 30); + selanAttackAnimation.AddFrames(2, 0, Vector(), 3); + selanAttackAnimation.AddFrames(2, 1, Vector(), 2); + selanAttackAnimation.AddFrames(2, 2, Vector(), 3); + selanAttackAnimation.AddFrames(2, 3, Vector(), 2); + selan.SetSpellAnimation(&selanSpellAnimation); SDL_Surface *guyImg(IMG_Load("test-data/guy.png")); Sprite guySprite(guyImg, 64, 64); @@ -125,8 +156,18 @@ int main(int argc, char **argv) { guy.SetMaxMana(0); guy.SetMana(0); guy.SetIP(254); - guy.SetAttackFrames(3, 125); - guy.SetSpellFrames(0, 125); + ComplexAnimation guyAttackAnimation(&guySprite, 30); + guyAttackAnimation.AddFrames(1, 0, Vector(-4, 0), 2); + guyAttackAnimation.AddFrames(1, 0, Vector(-8, 0), 2); + guyAttackAnimation.AddFrames(2, 0, Vector(-8, 0), 2); + guyAttackAnimation.AddFrame(2, 0, Vector(-4, 0)); + guyAttackAnimation.AddFrames(2, 0, Vector(), 2); + guyAttackAnimation.AddFrame(2, 1); + guyAttackAnimation.AddFrame(2, 1, Vector(4, 0)); + guyAttackAnimation.AddFrame(2, 1, Vector(10, 0)); + guyAttackAnimation.AddFrame(2, 2, Vector(10, 0)); + guyAttackAnimation.AddFrame(2, 2); + guy.SetAttackAnimation(&guyAttackAnimation); SDL_Surface *dekarImg(IMG_Load("test-data/dekar.png")); Sprite dekarSprite(dekarImg, 64, 64); @@ -139,8 +180,22 @@ int main(int argc, char **argv) { dekar.SetMaxMana(0); dekar.SetMana(0); dekar.SetIP(255); - dekar.SetAttackFrames(3, 125); - dekar.SetSpellFrames(3, 125); + ComplexAnimation dekarAttackAnimation(&dekarSprite, 30); + dekarAttackAnimation.AddFrame(1, 0, Vector(4, 0)); + dekarAttackAnimation.AddFrame(1, 0, Vector(8, 2)); + dekarAttackAnimation.AddFrame(2, 0, Vector(12, 4)); + dekarAttackAnimation.AddFrame(2, 0, Vector(16, 4)); + dekarAttackAnimation.AddFrames(2, 0, Vector(10, 2), 4); + dekarAttackAnimation.AddFrame(2, 1, Vector(6, 2)); + dekarAttackAnimation.AddFrame(2, 1, Vector()); + dekarAttackAnimation.AddFrame(2, 2, Vector(-2, 0)); + dekarAttackAnimation.AddFrames(2, 2, Vector(0, 0), 3); + dekar.SetAttackAnimation(&dekarAttackAnimation); + ComplexAnimation dekarSpellAnimation(&dekarSprite, 30); + dekarSpellAnimation.AddFrames(2, 0, Vector(), 6); + dekarSpellAnimation.AddFrames(2, 1, Vector(), 2); + dekarSpellAnimation.AddFrames(2, 2, Vector(), 3); + dekar.SetSpellAnimation(&dekarSpellAnimation); battle::Resources battleRes; diff --git a/test-data/dekar.png b/test-data/dekar.png index 5671f49..0f75139 100644 Binary files a/test-data/dekar.png and b/test-data/dekar.png differ diff --git a/test-data/guy.png b/test-data/guy.png index a292ec1..fc9330f 100644 Binary files a/test-data/guy.png and b/test-data/guy.png differ diff --git a/test-data/maxim.png b/test-data/maxim.png index bb195c1..6096510 100644 Binary files a/test-data/maxim.png and b/test-data/maxim.png differ diff --git a/test-data/selan.png b/test-data/selan.png index 7da4e59..72cce66 100644 Binary files a/test-data/selan.png and b/test-data/selan.png differ