diff --git a/engine/Board.cpp b/engine/Board.cpp index 9e041ec..371a08b 100644 --- a/engine/Board.cpp +++ b/engine/Board.cpp @@ -11,11 +11,23 @@ Board::Board(Game* parent) : void Board::RevealCard() { openCards.push_back(parent->GetStack().DrawCard()); - if (callback) - callback(openCards.back()); + if (revealCallback) + revealCallback(openCards.back()); +} + +void Board::Cleanup() +{ + openCards.clear(); + if (cleanupCallback) + cleanupCallback(); } void Board::SetRevealCallback(RevealCallbackFunc callbackFunc) { - callback = callbackFunc; + revealCallback = callbackFunc; +} + +void Board::SetCleanupCallback(CleanupCallbackFunc callbackFunc) +{ + cleanupCallback = callbackFunc; } diff --git a/engine/Board.hpp b/engine/Board.hpp index fb12eaa..d90fea4 100644 --- a/engine/Board.hpp +++ b/engine/Board.hpp @@ -6,22 +6,33 @@ #include "Card.hpp" typedef std::function)> RevealCallbackFunc; +typedef std::function CleanupCallbackFunc; class Game; +enum class BoardState +{ + Empty, + HasCards, + C +}; + class Board { public: Board(Game* parent); void RevealCard(); + void Cleanup(); inline const std::vector>& GetOpenCards() { return openCards; } void SetRevealCallback(RevealCallbackFunc callbackFunc); + void SetCleanupCallback(CleanupCallbackFunc callbackFunc); private: std::vector> openCards; - RevealCallbackFunc callback; + RevealCallbackFunc revealCallback; + CleanupCallbackFunc cleanupCallback; Game* parent; }; \ No newline at end of file diff --git a/engine/CardStack.cpp b/engine/CardStack.cpp index 4875412..a16a7d3 100644 --- a/engine/CardStack.cpp +++ b/engine/CardStack.cpp @@ -16,7 +16,7 @@ CardStack::CardStack() } // Shuffle stack - std::default_random_engine engine(time(0)); + std::default_random_engine engine(std::chrono::steady_clock::now().time_since_epoch().count()); std::shuffle(stack.begin(), stack.end(), engine); } diff --git a/engine/Game.cpp b/engine/Game.cpp index 4a63e98..8b79128 100644 --- a/engine/Game.cpp +++ b/engine/Game.cpp @@ -11,4 +11,10 @@ void Game::Setup() // Put 8 cards on the table for (int i = 0; i < 8; i++) board.RevealCard(); -} \ No newline at end of file +} + +void Game::Cleanup() +{ + stack = CardStack(); + board.Cleanup(); +} diff --git a/engine/Game.hpp b/engine/Game.hpp index 5b875d4..92739a8 100644 --- a/engine/Game.hpp +++ b/engine/Game.hpp @@ -10,6 +10,7 @@ public: ~Game() {} void Setup(); + void Cleanup(); inline CardStack& GetStack() { return stack; } inline Board& GetBoard() { return board; } diff --git a/src/Application.cpp b/src/Application.cpp index f08b7c8..b5d4cc5 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -53,6 +53,12 @@ void Application::OnKeyPressed(unsigned int character) if(!game.GetStack().Empty()) game.GetBoard().RevealCard(); } + + if (character == 'r' || character == 'R') + { + game.Cleanup(); + game.Setup(); + } } Application::Application() : @@ -94,8 +100,10 @@ Application::Application() : spdlog::debug("Setting up layers"); layerStack.push_back(new CardStackLayer(manager, game.GetStack())); + BoardLayer* boardLayer = new BoardLayer(manager, game.GetBoard()); game.GetBoard().SetRevealCallback(std::bind(&BoardLayer::OnRevealCard, boardLayer, std::placeholders::_1)); + game.GetBoard().SetCleanupCallback(std::bind(&BoardLayer::OnCleanup, boardLayer)); layerStack.push_back(boardLayer); spdlog::debug("Setting up game"); diff --git a/src/CardSprite.cpp b/src/CardSprite.cpp index 9ff03c2..c0d0213 100644 --- a/src/CardSprite.cpp +++ b/src/CardSprite.cpp @@ -66,6 +66,7 @@ void CardSprite::Update(double dt) if (t >= animation.duration) // Animation is finished { SetPosition(animation.to); + animation.onAnimationEnd(this); animationRunning = false; return; } diff --git a/src/CardSprite.hpp b/src/CardSprite.hpp index 3e51f14..2fe3a1a 100644 --- a/src/CardSprite.hpp +++ b/src/CardSprite.hpp @@ -3,12 +3,15 @@ #include #include "Card.hpp" +class CardSprite; + struct Animation { glm::vec3 from; glm::vec3 to; double alpha; double duration; + std::function onAnimationEnd = [](CardSprite*) {}; }; class CardSprite : public lol::Drawable, public lol::Transformable diff --git a/src/layers/BoardLayer.cpp b/src/layers/BoardLayer.cpp index 8227014..22e1439 100644 --- a/src/layers/BoardLayer.cpp +++ b/src/layers/BoardLayer.cpp @@ -10,21 +10,27 @@ BoardLayer::BoardLayer(lol::ObjectManager& manager, const Board& board) : void BoardLayer::OnUpdate() { double dt = Application::GetInstance().GetFrametime(); - for (CardSprite& sprite : sprites) - sprite.Update(dt); + for (CardSprite* sprite : sprites) + sprite->Update(dt); + + for (CardSprite* sprite : oldSprites) + sprite->Update(dt); } void BoardLayer::OnRender(lol::CameraBase& camera) { - for (CardSprite& sprite : sprites) - camera.Draw(sprite); + for (CardSprite* sprite : sprites) + camera.Draw(*sprite); + + for (CardSprite* sprite : oldSprites) + camera.Draw(*sprite); } void BoardLayer::OnRevealCard(std::shared_ptr card) { - sprites.push_back(CardSprite(manager, card)); - CardSprite& newCard = sprites.back(); - newCard.SetScale(glm::vec3(0.2f)); + sprites.push_back(new CardSprite(manager, 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 @@ -41,19 +47,19 @@ void BoardLayer::OnRevealCard(std::shared_ptr card) // If an even number of cards has been drawn, placce the last one below the previous one if (sprites.size() % 2 == 0) { - CardSprite& spriteBeforeLast = sprites[sprites.size() - 2]; + CardSprite* spriteBeforeLast = sprites[sprites.size() - 2]; cardPosition = glm::vec3( - spriteBeforeLast.GetAnimation().to.x, - spriteBeforeLast.GetAnimation().to.y - newCard.GetSize().y - 0.05f, + 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]; + CardSprite* secondSpriteBeforeLast = sprites[sprites.size() - 3]; cardPosition = glm::vec3( - secondSpriteBeforeLast.GetAnimation().to.x + newCard.GetSize().x + 0.05f, - secondSpriteBeforeLast.GetAnimation().to.y, + secondSpriteBeforeLast->GetAnimation().to.x + newCard->GetSize().x + 0.05f, + secondSpriteBeforeLast->GetAnimation().to.y, 0.0f ); } @@ -63,8 +69,8 @@ void BoardLayer::OnRevealCard(std::shared_ptr card) Animation anim{ glm::vec3( - 0.25f - 0.05 - newCard.GetSize().x, - 0.5f - newCard.GetSize().y * 0.5f, + 0.25f - 0.05 - newCard->GetSize().x, + 0.5f - newCard->GetSize().y * 0.5f, cardPosition.z ), // hardcode position of stack lol cardPosition, @@ -72,5 +78,35 @@ void BoardLayer::OnRevealCard(std::shared_ptr card) 0.2f }; - newCard.CreateAnimation(anim); + newCard->CreateAnimation(anim); +} + +void BoardLayer::OnCleanup() +{ + for (CardSprite* card : sprites) + { + Animation anim{ + card->GetPosition(), + glm::vec3( + 0.25f - 0.05 - card->GetSize().x, + 0.5f - card->GetSize().y * 0.5f, + card->GetPosition().z + ), + 2.5f, + 0.2f, + std::bind(&BoardLayer::OnCleanupAnimationEnd, this, std::placeholders::_1) + }; + + card->CreateAnimation(anim); + + oldSprites.push_back(card); + } + + sprites.clear(); +} + +void BoardLayer::OnCleanupAnimationEnd(CardSprite* sprite) +{ + oldSprites.erase(std::find(oldSprites.begin(), oldSprites.end(), sprite)); + delete sprite; } diff --git a/src/layers/BoardLayer.hpp b/src/layers/BoardLayer.hpp index 1e53404..4350143 100644 --- a/src/layers/BoardLayer.hpp +++ b/src/layers/BoardLayer.hpp @@ -13,10 +13,15 @@ public: void OnRender(lol::CameraBase& camera) override; void OnRevealCard(std::shared_ptr card); + void OnCleanup(); + +private: + void OnCleanupAnimationEnd(CardSprite* sprite); private: const Board& board; lol::ObjectManager& manager; - std::vector sprites; + std::vector sprites; + std::vector oldSprites; }; \ No newline at end of file