Improved animation system.

Now supports animation delays, canceling, and forcibly finishing animations.
See GuiComponent::cancelAnimation(), finishAnimation(), and new parameters for setAnimation().
This commit is contained in:
Aloshi 2014-04-18 12:19:46 -05:00
parent e842321b00
commit b968349864
6 changed files with 44 additions and 13 deletions

View file

@ -202,28 +202,31 @@ void GuiComponent::textInput(const char* text)
} }
} }
void GuiComponent::setAnimation(Animation* anim, std::function<void()> finishedCallback, bool reverse, unsigned char slot) void GuiComponent::setAnimation(Animation* anim, int delay, std::function<void()> finishedCallback, bool reverse, unsigned char slot)
{ {
assert(slot < MAX_ANIMATIONS); assert(slot < MAX_ANIMATIONS);
AnimationController* oldAnim = mAnimationMap[slot]; AnimationController* oldAnim = mAnimationMap[slot];
mAnimationMap[slot] = new AnimationController(anim, finishedCallback, reverse); mAnimationMap[slot] = new AnimationController(anim, delay, finishedCallback, reverse);
if(oldAnim) if(oldAnim)
delete oldAnim; delete oldAnim;
} }
void GuiComponent::stopAnimation(unsigned char slot) bool GuiComponent::stopAnimation(unsigned char slot)
{ {
assert(slot < MAX_ANIMATIONS); assert(slot < MAX_ANIMATIONS);
if(mAnimationMap[slot]) if(mAnimationMap[slot])
{ {
delete mAnimationMap[slot]; delete mAnimationMap[slot];
mAnimationMap[slot] = NULL; mAnimationMap[slot] = NULL;
return true;
}else{
return false;
} }
} }
void GuiComponent::cancelAnimation(unsigned char slot) bool GuiComponent::cancelAnimation(unsigned char slot)
{ {
assert(slot < MAX_ANIMATIONS); assert(slot < MAX_ANIMATIONS);
if(mAnimationMap[slot]) if(mAnimationMap[slot])
@ -231,6 +234,26 @@ void GuiComponent::cancelAnimation(unsigned char slot)
mAnimationMap[slot]->removeFinishedCallback(); mAnimationMap[slot]->removeFinishedCallback();
delete mAnimationMap[slot]; delete mAnimationMap[slot];
mAnimationMap[slot] = NULL; mAnimationMap[slot] = NULL;
return true;
}else{
return false;
}
}
bool GuiComponent::finishAnimation(unsigned char slot)
{
assert(slot < MAX_ANIMATIONS);
if(mAnimationMap[slot])
{
// skip to animation's end
const bool done = mAnimationMap[slot]->update(mAnimationMap[slot]->getAnimation()->getDuration() - mAnimationMap[slot]->getTime());
assert(done);
delete mAnimationMap[slot]; // will also call finishedCallback
mAnimationMap[slot] = NULL;
return true;
}else{
return false;
} }
} }

View file

@ -58,9 +58,10 @@ public:
bool isAnimationPlaying(unsigned char slot) const; bool isAnimationPlaying(unsigned char slot) const;
bool isAnimationReversed(unsigned char slot) const; bool isAnimationReversed(unsigned char slot) const;
int getAnimationTime(unsigned char slot) const; int getAnimationTime(unsigned char slot) const;
void setAnimation(Animation* animation, std::function<void()> finishedCallback = nullptr, bool reverse = false, unsigned char slot = 0); void setAnimation(Animation* animation, int delay = 0, std::function<void()> finishedCallback = nullptr, bool reverse = false, unsigned char slot = 0);
void stopAnimation(unsigned char slot); bool stopAnimation(unsigned char slot);
void cancelAnimation(unsigned char slot); // like stopAnimation, but doesn't call finishedCallback - only removes the animation, leaving things in their current state bool cancelAnimation(unsigned char slot); // like stopAnimation, but doesn't call finishedCallback - only removes the animation, leaving things in their current state
bool finishAnimation(unsigned char slot); // calls update(1.f) and finishedCallback, then deletes the animation - basically skips to the end
void stopAllAnimations(); void stopAllAnimations();
void cancelAllAnimations(); void cancelAllAnimations();

View file

@ -1,7 +1,7 @@
#include "AnimationController.h" #include "AnimationController.h"
AnimationController::AnimationController(Animation* anim, std::function<void()> finishedCallback, bool reverse) AnimationController::AnimationController(Animation* anim, int delay, std::function<void()> finishedCallback, bool reverse)
: mAnimation(anim), mFinishedCallback(finishedCallback), mReverse(reverse), mTime(0) : mAnimation(anim), mFinishedCallback(finishedCallback), mReverse(reverse), mTime(-delay), mDelay(delay)
{ {
} }
@ -16,6 +16,10 @@ AnimationController::~AnimationController()
bool AnimationController::update(int deltaTime) bool AnimationController::update(int deltaTime)
{ {
mTime += deltaTime; mTime += deltaTime;
if(mTime < 0) // are we still in delay?
return false;
float t = (float)mTime / mAnimation->getDuration(); float t = (float)mTime / mAnimation->getDuration();
if(t > 1.0f) if(t > 1.0f)

View file

@ -8,7 +8,7 @@ class AnimationController
{ {
public: public:
// Takes ownership of anim (will delete in destructor). // Takes ownership of anim (will delete in destructor).
AnimationController(Animation* anim, std::function<void()> finishedCallback = nullptr, bool reverse = false); AnimationController(Animation* anim, int delay = 0, std::function<void()> finishedCallback = nullptr, bool reverse = false);
virtual ~AnimationController(); virtual ~AnimationController();
// Returns true if the animation is complete. // Returns true if the animation is complete.
@ -16,7 +16,9 @@ public:
inline bool isReversed() const { return mReverse; } inline bool isReversed() const { return mReverse; }
inline int getTime() const { return mTime; } inline int getTime() const { return mTime; }
inline int getDelay() const { return mDelay; }
inline const std::function<void()>& getFinishedCallback() const { return mFinishedCallback; } inline const std::function<void()>& getFinishedCallback() const { return mFinishedCallback; }
inline Animation* getAnimation() const { return mAnimation; }
inline void removeFinishedCallback() { mFinishedCallback = nullptr; } inline void removeFinishedCallback() { mFinishedCallback = nullptr; }
@ -25,4 +27,5 @@ private:
std::function<void()> mFinishedCallback; std::function<void()> mFinishedCallback;
bool mReverse; bool mReverse;
int mTime; int mTime;
int mDelay;
}; };

View file

@ -112,12 +112,12 @@ void ViewController::launch(FileData* game, Eigen::Vector3f center)
center += mCurrentView->getPosition(); center += mCurrentView->getPosition();
stopAnimation(1); // make sure the fade in isn't still playing stopAnimation(1); // make sure the fade in isn't still playing
mLockInput = true; mLockInput = true;
setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 1500), [this, origCamera, center, game] setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 1500), 0, [this, origCamera, center, game]
{ {
game->getSystem()->launchGame(mWindow, game); game->getSystem()->launchGame(mWindow, game);
mCamera = origCamera; mCamera = origCamera;
mLockInput = false; mLockInput = false;
setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 600), nullptr, true); setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 600), 0, nullptr, true);
this->onFileChanged(game, FILE_METADATA_CHANGED); this->onFileChanged(game, FILE_METADATA_CHANGED);
}); });
} }

View file

@ -224,7 +224,7 @@ void DetailedGameListView::updateInfoPanel()
{ {
comp->setOpacity((unsigned char)(lerp<float>(0.0f, 1.0f, t)*255)); comp->setOpacity((unsigned char)(lerp<float>(0.0f, 1.0f, t)*255));
}; };
comp->setAnimation(new LambdaAnimation(func, 150), nullptr, fadingOut); comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut);
} }
} }
} }