From 758d57760953567c8ceeac29c3227cc82e889010 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Sat, 15 Jan 2022 18:05:36 +0100 Subject: [PATCH] added fancy animations --- src/Application.cpp | 10 +++++++++- src/Application.hpp | 5 +++++ src/CardSprite.cpp | 35 ++++++++++++++++++++++++++++++++- src/CardSprite.hpp | 17 ++++++++++++++++ src/layers/BoardLayer.cpp | 41 +++++++++++++++++++++++++++++---------- 5 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index bb0b83f..f08b7c8 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -24,9 +24,14 @@ void Application::Run() return; } + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + spdlog::debug("Launched Application"); while (!window->ShouldClose()) { + frametime = std::chrono::duration_cast>(std::chrono::steady_clock::now() - begin).count(); + begin = std::chrono::steady_clock::now(); + glfwPollEvents(); for (lol::Layer* layer : layerStack) @@ -44,7 +49,10 @@ void Application::Run() void Application::OnKeyPressed(unsigned int character) { if (character == 'd' || character == 'D') - game.GetBoard().RevealCard(); + { + if(!game.GetStack().Empty()) + game.GetBoard().RevealCard(); + } } Application::Application() : diff --git a/src/Application.hpp b/src/Application.hpp index 1bee718..17758d6 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "CardStack.hpp" @@ -22,6 +23,8 @@ public: void Run(); void OnKeyPressed(unsigned int character); // TODO: Remove later on + inline double GetFrametime() { return frametime; } + private: bool valid; Window* window; @@ -31,6 +34,8 @@ private: lol::ObjectManager manager; std::vector layerStack; + double frametime; + private: Application(); ~Application(); diff --git a/src/CardSprite.cpp b/src/CardSprite.cpp index f5c8fd4..9ff03c2 100644 --- a/src/CardSprite.cpp +++ b/src/CardSprite.cpp @@ -3,8 +3,14 @@ #include #include "ObjectIDs.hpp" +double ParametricCurve(double t, double alpha, double n) +{ + double power = pow(t / n, alpha); + return power / (power + pow(1.0f - t / n, alpha)); +} + CardSprite::CardSprite(lol::ObjectManager& manager, std::shared_ptr card) : - card(card) + card(card), animationRunning(false) { try { @@ -44,6 +50,33 @@ CardSprite::CardSprite(lol::ObjectManager& manager, std::shared_ptr card) ); } +void CardSprite::CreateAnimation(Animation animation) +{ + this->animation = animation; + t = 0.0; + animationRunning = true; +} + +void CardSprite::Update(double dt) +{ + if (!animationRunning) + return; + + t += dt; + if (t >= animation.duration) // Animation is finished + { + SetPosition(animation.to); + animationRunning = false; + return; + } + + double animVal = ParametricCurve(t, animation.alpha, animation.duration); + glm::vec3 distance = animation.to - animation.from; + glm::vec3 newPosition = animation.from + (float)animVal * distance; + + SetPosition(newPosition); +} + void CardSprite::PreRender(const lol::CameraBase& camera) { cards->Bind(); diff --git a/src/CardSprite.hpp b/src/CardSprite.hpp index d48327b..3e51f14 100644 --- a/src/CardSprite.hpp +++ b/src/CardSprite.hpp @@ -3,6 +3,14 @@ #include #include "Card.hpp" +struct Animation +{ + glm::vec3 from; + glm::vec3 to; + double alpha; + double duration; +}; + class CardSprite : public lol::Drawable, public lol::Transformable { public: @@ -10,6 +18,10 @@ public: glm::vec3 GetSize() { return glm::vec3(0.61035f, 1.0f, 0.0f) * GetScale(); } + void CreateAnimation(Animation animation); + inline const Animation& GetAnimation() { return animation; } + void Update(double dt); + private: void PreRender(const lol::CameraBase& camera) override; @@ -17,5 +29,10 @@ private: std::shared_ptr cards; glm::vec2 textureOffset; + // TODO: Create Animation handler? + Animation animation; + double t; + bool animationRunning; + std::shared_ptr card; }; \ No newline at end of file diff --git a/src/layers/BoardLayer.cpp b/src/layers/BoardLayer.cpp index b27e18c..8227014 100644 --- a/src/layers/BoardLayer.cpp +++ b/src/layers/BoardLayer.cpp @@ -1,5 +1,7 @@ #include "BoardLayer.hpp" +#include "../Application.hpp" + BoardLayer::BoardLayer(lol::ObjectManager& manager, const Board& board) : lol::Layer("Board"), manager(manager), board(board) { @@ -7,6 +9,9 @@ BoardLayer::BoardLayer(lol::ObjectManager& manager, const Board& board) : void BoardLayer::OnUpdate() { + double dt = Application::GetInstance().GetFrametime(); + for (CardSprite& sprite : sprites) + sprite.Update(dt); } void BoardLayer::OnRender(lol::CameraBase& camera) @@ -21,14 +26,15 @@ void BoardLayer::OnRevealCard(std::shared_ptr card) CardSprite& newCard = sprites.back(); newCard.SetScale(glm::vec3(0.2f)); + glm::vec3 cardPosition; // If this is the first card to be put on the board, place it in the top left slot if (sprites.size() == 1) { - newCard.SetPosition(glm::vec3( + cardPosition = glm::vec3( 0.25f + 0.05f, 0.5f + 0.025f, 0.0f - )); + ); } else { @@ -36,20 +42,35 @@ void BoardLayer::OnRevealCard(std::shared_ptr card) if (sprites.size() % 2 == 0) { CardSprite& spriteBeforeLast = sprites[sprites.size() - 2]; - newCard.SetPosition(glm::vec3( - spriteBeforeLast.GetPosition().x, - spriteBeforeLast.GetPosition().y - newCard.GetSize().y - 0.05f, + cardPosition = glm::vec3( + spriteBeforeLast.GetAnimation().to.x, + spriteBeforeLast.GetAnimation().to.y - newCard.GetSize().y - 0.05f, 0.0f - )); + ); } else // Else, place it in the next row { CardSprite& secondSpriteBeforeLast = sprites[sprites.size() - 3]; - newCard.SetPosition(glm::vec3( - secondSpriteBeforeLast.GetPosition().x + newCard.GetSize().x + 0.05f, - secondSpriteBeforeLast.GetPosition().y, + cardPosition = glm::vec3( + secondSpriteBeforeLast.GetAnimation().to.x + newCard.GetSize().x + 0.05f, + secondSpriteBeforeLast.GetAnimation().to.y, 0.0f - )); + ); } } + + cardPosition.z = 1.0f + sprites.size(); + + Animation anim{ + glm::vec3( + 0.25f - 0.05 - newCard.GetSize().x, + 0.5f - newCard.GetSize().y * 0.5f, + cardPosition.z + ), // hardcode position of stack lol + cardPosition, + 2.5f, + 0.2f + }; + + newCard.CreateAnimation(anim); }