mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Added a fade in from black for ViewController.
Added LambdaAnimation (which lets you use a lambda for the apply method). Useful for simple one-off animations. Added animation slots - only one animation can play per slot. This way you can have two animations run at the same time.
This commit is contained in:
parent
67818d5727
commit
7e9b20fac5
|
@ -203,6 +203,7 @@ set(ES_HEADERS
|
|||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/Animation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/AnimationController.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/LambdaAnimation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/LaunchAnimation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/animations/MoveCameraAnimation.h
|
||||
|
||||
|
|
|
@ -7,12 +7,20 @@
|
|||
GuiComponent::GuiComponent(Window* window) : mWindow(window), mParent(NULL), mOpacity(255),
|
||||
mPosition(Eigen::Vector3f::Zero()), mSize(Eigen::Vector2f::Zero()), mTransform(Eigen::Affine3f::Identity())
|
||||
{
|
||||
for(unsigned char i = 0; i < MAX_ANIMATIONS; i++)
|
||||
mAnimationMap[i] = NULL;
|
||||
}
|
||||
|
||||
GuiComponent::~GuiComponent()
|
||||
{
|
||||
mWindow->removeGui(this);
|
||||
|
||||
for(unsigned char i = 0; i < MAX_ANIMATIONS; i++)
|
||||
{
|
||||
if(mAnimationMap[i])
|
||||
delete mAnimationMap[i];
|
||||
}
|
||||
|
||||
if(mParent)
|
||||
mParent->removeChild(this);
|
||||
|
||||
|
@ -33,8 +41,19 @@ bool GuiComponent::input(InputConfig* config, Input input)
|
|||
|
||||
void GuiComponent::update(int deltaTime)
|
||||
{
|
||||
if(mAnimationController)
|
||||
mAnimationController->update(deltaTime);
|
||||
for(unsigned char i = 0; i < MAX_ANIMATIONS; i++)
|
||||
{
|
||||
AnimationController* anim = mAnimationMap[i];
|
||||
if(anim)
|
||||
{
|
||||
bool done = anim->update(deltaTime);
|
||||
if(done)
|
||||
{
|
||||
mAnimationMap[i] = NULL;
|
||||
delete anim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
|
@ -186,12 +205,23 @@ void GuiComponent::textInput(const char* text)
|
|||
}
|
||||
}
|
||||
|
||||
void GuiComponent::setAnimation(Animation* anim, std::function<void()> finishedCallback, bool reverse)
|
||||
void GuiComponent::setAnimation(Animation* anim, std::function<void()> finishedCallback, bool reverse, unsigned char slot)
|
||||
{
|
||||
mAnimationController = std::shared_ptr<AnimationController>(new AnimationController(anim, finishedCallback, reverse));
|
||||
assert(slot < MAX_ANIMATIONS);
|
||||
|
||||
AnimationController* oldAnim = mAnimationMap[slot];
|
||||
mAnimationMap[slot] = new AnimationController(anim, finishedCallback, reverse);
|
||||
|
||||
if(oldAnim)
|
||||
delete oldAnim;
|
||||
}
|
||||
|
||||
void GuiComponent::stopAnimation()
|
||||
void GuiComponent::stopAnimation(unsigned char slot)
|
||||
{
|
||||
mAnimationController.reset();
|
||||
assert(slot < MAX_ANIMATIONS);
|
||||
if(mAnimationMap[slot])
|
||||
{
|
||||
delete mAnimationMap[slot];
|
||||
mAnimationMap[slot] = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ public:
|
|||
GuiComponent* getChild(unsigned int i) const;
|
||||
|
||||
// animation will be automatically deleted when it completes or is stopped.
|
||||
void setAnimation(Animation* animation, std::function<void()> finishedCallback = nullptr, bool reverse = false);
|
||||
void stopAnimation();
|
||||
void setAnimation(Animation* animation, std::function<void()> finishedCallback = nullptr, bool reverse = false, unsigned char slot = 0);
|
||||
void stopAnimation(unsigned char slot);
|
||||
|
||||
virtual unsigned char getOpacity() const;
|
||||
virtual void setOpacity(unsigned char opacity);
|
||||
|
@ -78,9 +78,12 @@ protected:
|
|||
Eigen::Vector3f mPosition;
|
||||
Eigen::Vector2f mSize;
|
||||
|
||||
public:
|
||||
const static unsigned char MAX_ANIMATIONS = 4;
|
||||
|
||||
private:
|
||||
Eigen::Affine3f mTransform; //Don't access this directly! Use getTransform()!
|
||||
std::shared_ptr<AnimationController> mAnimationController;
|
||||
AnimationController* mAnimationMap[MAX_ANIMATIONS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,7 @@ AnimationController::~AnimationController()
|
|||
delete mAnimation;
|
||||
}
|
||||
|
||||
void AnimationController::update(int deltaTime)
|
||||
bool AnimationController::update(int deltaTime)
|
||||
{
|
||||
mTime += deltaTime;
|
||||
float t = (float)mTime / mAnimation->getDuration();
|
||||
|
@ -26,13 +26,7 @@ void AnimationController::update(int deltaTime)
|
|||
mAnimation->apply(mReverse ? 1.0f - t : t);
|
||||
|
||||
if(t == 1.0f)
|
||||
{
|
||||
if(mFinishedCallback)
|
||||
{
|
||||
// in case mFinishedCallback causes us to be deleted, use a copy
|
||||
auto copy = mFinishedCallback;
|
||||
mFinishedCallback = nullptr;
|
||||
copy();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ public:
|
|||
AnimationController(Animation* anim, std::function<void()> finishedCallback = nullptr, bool reverse = false);
|
||||
virtual ~AnimationController();
|
||||
|
||||
void update(int deltaTime);
|
||||
// Returns true if the animation is complete.
|
||||
bool update(int deltaTime);
|
||||
|
||||
private:
|
||||
Animation* mAnimation;
|
||||
|
|
20
src/animations/LambdaAnimation.h
Normal file
20
src/animations/LambdaAnimation.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "Animation.h"
|
||||
|
||||
class LambdaAnimation : public Animation
|
||||
{
|
||||
public:
|
||||
LambdaAnimation(const std::function<void(float t)>& func, int duration) : mFunction(func), mDuration(duration) {}
|
||||
|
||||
int getDuration() const override { return mDuration; }
|
||||
|
||||
void apply(float t) override
|
||||
{
|
||||
mFunction(t);
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(float t)> mFunction;
|
||||
int mDuration;
|
||||
};
|
|
@ -182,7 +182,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
bool sleeping = false;
|
||||
unsigned int timeSinceLastEvent = 0;
|
||||
int lastTime = 0;
|
||||
int lastTime = SDL_GetTicks();
|
||||
bool running = true;
|
||||
|
||||
while(running)
|
||||
|
@ -230,8 +230,8 @@ int main(int argc, char* argv[])
|
|||
deltaTime = 1000;
|
||||
|
||||
window.update(deltaTime);
|
||||
Renderer::swapBuffers(); //swap here so we can read the last screen state during updates (see ImageComponent::copyScreen())
|
||||
window.render();
|
||||
Renderer::swapBuffers();
|
||||
|
||||
//sleep if we're past our threshold
|
||||
//sleeping entails setting a flag to start skipping frames
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
#include "GridGameListView.h"
|
||||
#include "../animations/LaunchAnimation.h"
|
||||
#include "../animations/MoveCameraAnimation.h"
|
||||
#include "../animations/LambdaAnimation.h"
|
||||
|
||||
ViewController::ViewController(Window* window)
|
||||
: GuiComponent(window), mCurrentView(nullptr), mCamera(Eigen::Affine3f::Identity()), mFadeOpacity(0)
|
||||
: GuiComponent(window), mCurrentView(nullptr), mCamera(Eigen::Affine3f::Identity()), mFadeOpacity(1)
|
||||
{
|
||||
// slot 1 so the fade carries over
|
||||
setAnimation(new LambdaAnimation([&] (float t) { mFadeOpacity = lerp<float>(1.0f, 0.0f, t); }, 900), nullptr, false, 1);
|
||||
mState.viewing = START_SCREEN;
|
||||
}
|
||||
|
||||
|
@ -95,11 +98,13 @@ void ViewController::launch(FileData* game, Eigen::Vector3f center)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
game->getSystem()->getTheme()->playSound("gameSelectSound");
|
||||
|
||||
Eigen::Affine3f origCamera = mCamera;
|
||||
origCamera.translation() = -mCurrentView->getPosition();
|
||||
|
||||
center += mCurrentView->getPosition();
|
||||
stopAnimation(1); // make sure the fade in isn't still playing
|
||||
setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 1500), [this, origCamera, center, game]
|
||||
{
|
||||
game->getSystem()->launchGame(mWindow, game);
|
||||
|
|
Loading…
Reference in a new issue