From 8456b7dac2051bfd2b507a39854c1428eb4d91cd Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 14 Aug 2012 21:51:57 +0200 Subject: [PATCH] added Maxim's melee animation --- src/app/Application.cpp | 2 +- src/battle/AttackAnimation.cpp | 4 ++++ src/battle/AttackAnimation.h | 1 + src/battle/Hero.h | 6 ++++++ src/battle/states/PerformAttacks.cpp | 25 ++++++++++++++++++--- src/battle/states/PerformAttacks.h | 5 ++++- src/main.cpp | 31 ++++++++++++++++++++------- test-data/melee-maxim.png | Bin 0 -> 1637 bytes 8 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 test-data/melee-maxim.png diff --git a/src/app/Application.cpp b/src/app/Application.cpp index c1e4f15..6e46203 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -121,7 +121,7 @@ void Application::Loop() { Uint32 now(SDL_GetTicks()); Uint32 deltaT(now - last); GlobalTimers().Update(deltaT); - if (deltaT > 34) deltaT = 34; + if (deltaT > 30) deltaT = 30; if (CurrentState()) { CurrentState()->GraphicsTimers().Update(deltaT); diff --git a/src/battle/AttackAnimation.cpp b/src/battle/AttackAnimation.cpp index 0aedf18..07148db 100644 --- a/src/battle/AttackAnimation.cpp +++ b/src/battle/AttackAnimation.cpp @@ -160,6 +160,10 @@ bool AttackAnimation::ExecuteWaitAnimations() { } +bool AttackAnimation::Running() const { + return cursor >= 0 && !Finished(); +} + bool AttackAnimation::Finished() const { return cursor >= int(text.size()); } diff --git a/src/battle/AttackAnimation.h b/src/battle/AttackAnimation.h index 7758bb8..48b1a5d 100644 --- a/src/battle/AttackAnimation.h +++ b/src/battle/AttackAnimation.h @@ -40,6 +40,7 @@ public: public: void Start(BattleState *, app::State *); void Update(); + bool Running() const; bool Finished() const; void Render(SDL_Surface *screen, const geometry::Vector &offset) const; diff --git a/src/battle/Hero.h b/src/battle/Hero.h index 97a21c2..c0bd41a 100644 --- a/src/battle/Hero.h +++ b/src/battle/Hero.h @@ -22,6 +22,8 @@ namespace graphics { namespace battle { +class AttackAnimation; + class Hero { public: @@ -69,6 +71,8 @@ public: bool HasRing() const { return ring; } bool HasJewel() const { return jewel; } + class AttackAnimation *MeleeAnimation() { return meleeAnimation; } + const class AttackAnimation *MeleeAnimation() const { return meleeAnimation; } graphics::Animation *AttackAnimation() { return attackAnimation; } const graphics::Animation *AttackAnimation() const { return attackAnimation; } graphics::Animation *SpellAnimation() { return spellAnimation; } @@ -95,6 +99,7 @@ public: void AddSpell(const common::Spell *s) { spells.push_back(s); } + void SetMeleeAnimation(class AttackAnimation *a) { meleeAnimation = a; } void SetAttackAnimation(graphics::Animation *a) { attackAnimation = a; } void SetSpellAnimation(graphics::Animation *a) { spellAnimation = a; } @@ -109,6 +114,7 @@ private: const common::Item *ring; const common::Item *jewel; + class AttackAnimation *meleeAnimation; graphics::Animation *attackAnimation; graphics::Animation *spellAnimation; diff --git a/src/battle/states/PerformAttacks.cpp b/src/battle/states/PerformAttacks.cpp index dd0e0df..6c318aa 100644 --- a/src/battle/states/PerformAttacks.cpp +++ b/src/battle/states/PerformAttacks.cpp @@ -7,6 +7,7 @@ #include "PerformAttacks.h" +#include "../AttackAnimation.h" #include "../BattleState.h" #include "../Hero.h" #include "../Monster.h" @@ -57,6 +58,7 @@ void PerformAttacks::Resize(int width, int height) { void PerformAttacks::HandleEvents(const Input &input) { + if (attackAnimation) attackAnimation->Update(); CheckNumberAnimation(); if (HasAnimationsRunning()) return; ResetAnimation(); @@ -77,8 +79,19 @@ void PerformAttacks::HandleEvents(const Input &input) { switch (ac.GetType()) { case AttackChoice::SWORD: - titleBarText = hero.HasWeapon() ? hero.Weapon()->Name() : "Melee attack!"; - moveAnimation = hero.AttackAnimation(); + if (hero.HasWeapon()) { + titleBarText = hero.Weapon()->Name(); + moveAnimation = hero.AttackAnimation(); + } else { + titleBarText = "Melee attack!"; + if (hero.MeleeAnimation()) { + moveAnimation = 0; + attackAnimation = hero.MeleeAnimation(); + } else { + moveAnimation = hero.AttackAnimation(); + attackAnimation = 0; + } + } numberAnimation.push_back(NumberAnimation(15, battle->Res().numberAnimationPrototype, battle->Res().bigNumberSprite)); if (ac.Selection().TargetsEnemies()) { numberPosition.push_back( @@ -119,11 +132,15 @@ void PerformAttacks::HandleEvents(const Input &input) { if (titleBarText) titleBarTimer = GraphicsTimers().StartCountdown(1500); if (moveAnimation) moveAnimation->Start(*this); + if (attackAnimation) attackAnimation->Start(battle, this); } void PerformAttacks::CheckNumberAnimation() { if (moveAnimation && moveAnimation->Running()) return; - if (!moveAnimation || moveAnimation->JustFinished()) { + if (attackAnimation && !attackAnimation->Finished()) return; + if (moveAnimation || attackAnimation) { + moveAnimation = 0; + attackAnimation = 0; for (vector::iterator i(numberAnimation.begin()), end(numberAnimation.end()); i != end; ++i) { i->Start(*this); } @@ -145,6 +162,7 @@ bool PerformAttacks::HasAnimationsRunning() const { void PerformAttacks::ResetAnimation() { if (moveAnimation) moveAnimation->Stop(); + if (attackAnimation) attackAnimation = 0; titleBarTimer.Clear(); numberAnimation.clear(); numberPosition.clear(); @@ -175,6 +193,7 @@ void PerformAttacks::Render(SDL_Surface *screen) { battle->RenderSmallHeroTags(screen, offset); RenderTitleBar(screen, offset); RenderNumbers(screen, offset); + if (attackAnimation) attackAnimation->Render(screen, offset); } void PerformAttacks::RenderTitleBar(SDL_Surface *screen, const Vector &offset) { diff --git a/src/battle/states/PerformAttacks.h b/src/battle/states/PerformAttacks.h index a5f3247..a4d58dc 100644 --- a/src/battle/states/PerformAttacks.h +++ b/src/battle/states/PerformAttacks.h @@ -19,12 +19,14 @@ namespace battle { +class AttackAnimation; + class PerformAttacks : public app::State { public: explicit PerformAttacks(BattleState *battle) - : ctrl(0), battle(battle), moveAnimation(0), titleBarText(0), cursor(-1) { } + : ctrl(0), battle(battle), moveAnimation(0), attackAnimation(0), titleBarText(0), cursor(-1) { } public: virtual void EnterState(app::Application &ctrl, SDL_Surface *screen); @@ -53,6 +55,7 @@ private: app::Application *ctrl; BattleState *battle; graphics::Animation *moveAnimation; + AttackAnimation *attackAnimation; const char *titleBarText; app::Timer titleBarTimer; std::vector order; diff --git a/src/main.cpp b/src/main.cpp index 0fd129b..49a79b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "app/Application.h" #include "app/Input.h" +#include "battle/AttackAnimation.h" #include "battle/BattleState.h" #include "battle/Hero.h" #include "battle/Monster.h" @@ -23,6 +24,7 @@ #include "graphics/Frame.h" #include "graphics/Gauge.h" #include "graphics/Menu.h" +#include "graphics/SimpleAnimation.h" #include "graphics/Sprite.h" #include "sdl/InitImage.h" #include "sdl/InitScreen.h" @@ -35,6 +37,7 @@ using app::Application; using app::Input; +using battle::AttackAnimation; using battle::BattleState; using battle::Hero; using battle::Monster; @@ -50,6 +53,7 @@ using graphics::Font; using graphics::Frame; using graphics::Gauge; using graphics::Menu; +using graphics::SimpleAnimation; using graphics::Sprite; using sdl::InitImage; using sdl::InitScreen; @@ -102,18 +106,29 @@ int main(int argc, char **argv) { maxim.SetMana(20); maxim.SetIP(0); 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)); + maximAttackAnimation.AddFrame(1, 0, Vector(2, 0)); + maximAttackAnimation.AddFrame(1, 0, Vector(2, -1)); + maximAttackAnimation.AddFrames(2, 0, Vector(2, -2), 2); + maximAttackAnimation.AddFrame(2, 0, Vector(4, -2)); + maximAttackAnimation.AddFrame(2, 0, Vector(3, -1)); + maximAttackAnimation.AddFrames(2, 1, Vector(3, -1), 2); + maximAttackAnimation.AddFrame(2, 1); + maximAttackAnimation.AddFrames(2, 2, Vector(), 2); maxim.SetAttackAnimation(&maximAttackAnimation); ComplexAnimation maximSpellAnimation(&maximSprite, 150); maximSpellAnimation.AddFrames(3, 0, Vector(), 2); maximSpellAnimation.AddFrame(3, 1); maxim.SetSpellAnimation(&maximSpellAnimation); + SDL_Surface *maximMeleeImg(IMG_Load("test-data/melee-maxim.png")); + Sprite maximMeleeSprite(maximMeleeImg, 96, 96); + SimpleAnimation maximMeleeAnimation(&maximMeleeSprite, 30, 4); + AttackAnimation maximMeleeScript; + maximMeleeScript.PlayAttackAnimation(); + maximMeleeScript.StartTimer(150); + maximMeleeScript.WaitForTimer(); + maximMeleeScript.PlayTargetAnimation(&maximMeleeAnimation); + maximMeleeScript.WaitForAnimations(); + maxim.SetMeleeAnimation(&maximMeleeScript); SDL_Surface *selanImg(IMG_Load("test-data/selan.png")); Sprite selanSprite(selanImg, 64, 64); @@ -442,7 +457,7 @@ int main(int argc, char **argv) { firestorm.GetTargetingMode().TargetAllEnemies(); firestorm.SetPhysical(); zircoSword.SetIkari(&firestorm); - maxim.SetWeapon(&zircoSword); +// maxim.SetWeapon(&zircoSword); Item zirconArmor; zirconArmor.SetName("Zircon armor"); zirconArmor.SetMenuIcon(&armorIcon); diff --git a/test-data/melee-maxim.png b/test-data/melee-maxim.png new file mode 100644 index 0000000000000000000000000000000000000000..3e296af1aec64f32ff2519d17be073985af85493 GIT binary patch literal 1637 zcmZ{kZ&Z?J7{+;lvbP=o^txteb6O2_!P1s1%~G^1Q}a(KNV<^LEK8S~LsJkaZK*AF zCF;!7)|{dUT4^RC&xsN1^Bfb&nBZJxCz3r-oGIH0V!Q9I+`@d}G^L~^Xp=z#( z^j2P?aJuxn1&(wFptQ5AmnNPYx!m0FCGjj(6UN){Qc2*F=E^4b1?I@N5@h@Q;4F^F zY&v*!QLrX`6)P|?(b;hw0JWAD*{^2Bz+0|5^@&r%gQ2y+d(CF*U4=4r?o1Rs z(}vwER}y5JS6ih%mNLO{HE~}cwKp~nuI0MyDApBrt}jP{ovm#|*{6J0zIFo$;sVe| zsF$^h(4bDT8*+ieA$l$0Knw9Oa4WBk;cki5EHMu#2cKjla zab)yE0;zshJ*H1gRT%6W-)Pn}TSoj`)n=nU>uAeV2LbSkSD$D~ROl?69(ZEr?{4}< za(>_UlshfT6S;KsEYFb@@Qv71b$ya~SgocBEXBi`Wxj2OaKzQ1CyxaSe&enQez#OE zk<3RGD8KPOrJe|1n3vXN7VBl)$<8)JA&yalo7J6Zt?_9xTZ~No_UO_LNySOi+WGFV z?6M-U@Mmok8!Y9W4qc|MKO|inV^!DcqeD03hH|AN$sDcuPgU%o&0)kDpNyu$!WGev z8m=b9Hk(@`N>O0tv5)&Bz3ScB+0viRQ8_Uod#cNY7-7C=8L!i$Ao{_RsRtR>eq}1V zM`$C&;23`e^(jk2q3`J1KC1k_jYvmc_d;2ll>0dofd-o*G2jEx9S30~r{^LzNGo`z zw!N}Y^n{G)=orHki+m2gc6FZ4EJgV-KH`&}ZaE0{V+QxbVL#^J7|CFz&=4Oh|9}od z4E&ChP_O>tMyUbM@bat6G|j}bcJ466a_ku*ne93N@sHR)JP>{H+gqXx88#&o?@Tle z)I{k3jm}i7!qDFOuBA>3LVT(?F0m9CYHfGf)am}kFO61j%Djx!+EG-20+Vo8=kr7< zJxJ^0398~|pm)&`&v!j>5^nBF9v8c9CTsN5#=9oBa#XbukK%g*R-4L99OKFdOWq5M zM)tFfa|)dVZ#x?A=HjiY`2yN>Bdb|pKCNia9HWII9=Sx-p0x9K$Q;(0R-IRzwd6mb zUm9JU9)DXuwaX3231~ETUZW3rT_=fR*fLq#scto8uF){5inn zahi&Z?CQ)2OV7H%9MlsWSAzDTvgEOqfU1?CnL8l;7x7x-^HY<0^p4TNY1T^v}uV>RU$Ty!Z` zxE%;4zIaTc^k7pq0l5%ID@1sgfId~ly$is<-xV#N3nXV{I9hK!82DF6$nJ