From 073d6ba7ad9f4052dcefd0fc64fd705b0e9c8f79 Mon Sep 17 00:00:00 2001 From: Philipp Sehmisch Date: Wed, 20 Sep 2006 23:34:11 +0000 Subject: tweaks at the animation system (mostly about fixing the looping attack animations of the monsters) --- ChangeLog | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- src/animatedsprite.cpp | 26 +++++++++++++------------- src/animatedsprite.h | 5 ++--- src/animation.cpp | 33 ++++++++++++++++++++++++++++----- src/animation.h | 16 ++++++++++++++++ src/being.cpp | 25 +++++++++++++++---------- 6 files changed, 123 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c43fb6f..5ab04e76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,52 @@ -2006-09-20 Philipp Sehmisch +2006-09-21 Philipp Sehmisch + + * src/animation.cpp, src/animation.h, src/animatedsprite.cpp, + src/animatedsprite.h: Removed some obsolete code and implemented + the posibility to define an token in the s + that allows to define an animation that doesn't loop and returns + to the STAND animation when finished. + * data/graphics/sprites/hairstyle1.xml, + data/graphics/sprites/hairstyle2.xml, + data/graphics/sprites/hairstyle3.xml, + data/graphics/sprites/hairstyle4.xml, + data/graphics/sprites/hairstyle5.xml, + data/graphics/sprites/hairstyle6.xml, + data/graphics/sprites/hairstyle7.xml, + data/graphics/sprites/item001.xml, + data/graphics/sprites/item002.xml, + data/graphics/sprites/item003.xml, + data/graphics/sprites/item004.xml, + data/graphics/sprites/item005.xml, + data/graphics/sprites/item006.xml, + data/graphics/sprites/item007.xml, + data/graphics/sprites/item008.xml, + data/graphics/sprites/item009.xml, + data/graphics/sprites/item010.xml, + data/graphics/sprites/monster0.xml, + data/graphics/sprites/monster1.xml, + data/graphics/sprites/monster2.xml, + data/graphics/sprites/monster3.xml, + data/graphics/sprites/monster4.xml, + data/graphics/sprites/monster5.xml, + data/graphics/sprites/monster6.xml, + data/graphics/sprites/monster7.xml, + data/graphics/sprites/monster8.xml, + data/graphics/sprites/monster9.xml, + data/graphics/sprites/monster10.xml, + data/graphics/sprites/monster11.xml, + data/graphics/sprites/monster12.xml, + data/graphics/sprites/monster13.xml, + data/graphics/sprites/monster14.xml, + data/graphics/sprites/monster15.xml, + data/graphics/sprites/monster16.xml, + data/graphics/sprites/monster17.xml, + data/graphics/sprites/monster18.xml, + data/graphics/sprites/monster19.xml, + data/graphics/sprites/weapons.xml: + Used the token for all attack animations fixing the problem + with looping monster attack animations. + +2006-09-20 Philipp Sehmisch * data/graphics/items/generic-whitefur.png, data/graphics/items/generic-cavesnakelamp.png, diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp index 36851366..e7439644 100644 --- a/src/animatedsprite.cpp +++ b/src/animatedsprite.cpp @@ -176,6 +176,10 @@ AnimatedSprite::AnimatedSprite(const std::string& animationFile, int variant): start++; } } + else if (xmlStrEqual(phaseNode->name, BAD_CAST "end")) + { + animation->addTerminator(); + }; } // for phaseNode } // for animationNode } // if "" else if "" @@ -268,7 +272,7 @@ AnimatedSprite::reset() } void -AnimatedSprite::play(SpriteAction action, int time) +AnimatedSprite::play(SpriteAction action) { ActionIterator i = mActions.find(action); @@ -282,23 +286,14 @@ AnimatedSprite::play(SpriteAction action, int time) if (mAction != i->second) { mAction = i->second; - mLastTime = 0; - } - - if (!mAction || !time) - mSpeed = 1.0f; - else { - Animation* animation= mAction->getAnimation(mDirection); - if (animation) { - int animationLength = animation->getLength(); - mSpeed = (float) animationLength / time; - } + //mAction->reset(); } } void AnimatedSprite::update(int time) { + bool notFinished = true; // Avoid freaking out at first frame or when tick_time overflows if (time < mLastTime || mLastTime == 0) mLastTime = time; @@ -308,9 +303,14 @@ AnimatedSprite::update(int time) { Animation *animation = mAction->getAnimation(mDirection); if (animation != NULL) { - animation->update((unsigned int)((time - mLastTime) * mSpeed));} + notFinished = animation->update((unsigned int)(time - mLastTime));} mLastTime = time; } + + if (!notFinished) + { + play(ACTION_STAND); + } } bool diff --git a/src/animatedsprite.h b/src/animatedsprite.h index ea661d94..e87a9885 100644 --- a/src/animatedsprite.h +++ b/src/animatedsprite.h @@ -88,11 +88,10 @@ class AnimatedSprite reset(); /** - * Plays an action using the current direction that will have a - * duration of the specified time, 0 means default. + * Plays an action using the current direction */ void - play(SpriteAction action, int time = 0); + play(SpriteAction action); /** * Inform the animation of the passed time so that it can output the diff --git a/src/animation.cpp b/src/animation.cpp index c1b27ebd..98a4abb8 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -39,45 +39,68 @@ Animation::reset() iCurrentPhase = mAnimationPhases.begin(); } -void + +bool Animation::update(unsigned int time) { mTime += time; if (mAnimationPhases.empty()) - return; + return true; + if (isTerminator(*iCurrentPhase)) + return false; unsigned int delay = iCurrentPhase->delay; - if (!delay) - return; while (mTime > delay) { + if (!delay) + return true; mTime -= delay; iCurrentPhase++; if (iCurrentPhase == mAnimationPhases.end()) { iCurrentPhase = mAnimationPhases.begin(); } + if (isTerminator(*iCurrentPhase)) + return false; + delay = iCurrentPhase->delay; } + return true; } + int Animation::getCurrentPhase() const { return mAnimationPhases.empty() ? -1 : iCurrentPhase->image; } + void Animation::addPhase(int image, unsigned int delay, int offsetX, int offsetY) { //add new phase to animation list - AnimationPhase newPhase = { image, delay, offsetX, offsetY }; + AnimationPhase newPhase = { image, delay, offsetX, offsetY}; mAnimationPhases.push_back(newPhase); //reset animation circle iCurrentPhase = mAnimationPhases.begin(); } +void +Animation::addTerminator() +{ + AnimationPhase terminator = { -1, 0, 0, 0}; + mAnimationPhases.push_back(terminator); + iCurrentPhase = mAnimationPhases.begin(); +} + +bool +Animation::isTerminator(AnimationPhase candidate) +{ + return (candidate.image < 0); +} + int Animation::getLength() { diff --git a/src/animation.h b/src/animation.h index 60dcd287..605d8cb1 100644 --- a/src/animation.h +++ b/src/animation.h @@ -61,10 +61,25 @@ class Animation void reset(); + /** + * Appends a new animation at the end of the sequence + */ void addPhase(int image, unsigned int delay, int offsetX, int offsetY); + /** + * Appends an animation terminator that states that the animation + * should not loop + */ void + addTerminator(); + + /** + * Updates animation phase. + * true indicates a still running animation while false indicates a + * finished animation + */ + bool update(unsigned int time); int @@ -89,6 +104,7 @@ class Animation getLength(); protected: + static bool isTerminator(AnimationPhase); std::list mAnimationPhases; std::list::iterator iCurrentPhase; unsigned int mTime; diff --git a/src/being.cpp b/src/being.cpp index 1ca8929a..e7b27f43 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -190,10 +190,24 @@ Being::setAction(Uint8 action) currentAction = ACTION_ATTACK; break; } + for (int i = 0; i < VECTOREND_SPRITE; i++) + { + if (mSprites[i]) + { + mSprites[i]->reset(); + } + } }; break; case MONSTER_ATTACK: currentAction = ACTION_ATTACK; + for (int i = 0; i < VECTOREND_SPRITE; i++) + { + if (mSprites[i]) + { + mSprites[i]->reset(); + } + } break; case DEAD: currentAction = ACTION_DEAD; @@ -205,16 +219,7 @@ Being::setAction(Uint8 action) for (int i = 0; i < VECTOREND_SPRITE; i++) { - if (!mSprites[i]) - continue; - - if (currentAction == ACTION_ATTACK || - currentAction == ACTION_ATTACK_STAB || - currentAction == ACTION_ATTACK_BOW) - { - mSprites[i]->play(currentAction, mAttackSpeed); - } - else + if (mSprites[i]) { mSprites[i]->play(currentAction); } -- cgit v1.2.3-70-g09d2