From cf504ccc6abf74fc07a9dace39314c477c4d1df9 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Sat, 12 Jun 2021 17:47:11 +0100 Subject: [PATCH] Solitaire: Allow automatic moves to end the game and animate Previously, if a tab-move moved all the remaining cards to the foundations, the game would not notice until you moved a card away and then back again. I had to add a 1-frame delay to starting the animation, so that it would have time to re-paint the foundation in that case. --- Userland/Games/Solitaire/Game.cpp | 27 +++++++++++++++++++-------- Userland/Games/Solitaire/Game.h | 1 + 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Userland/Games/Solitaire/Game.cpp b/Userland/Games/Solitaire/Game.cpp index bd6459636e..45e23c0642 100644 --- a/Userland/Games/Solitaire/Game.cpp +++ b/Userland/Games/Solitaire/Game.cpp @@ -49,7 +49,10 @@ static float rand_float() void Game::timer_event(Core::TimerEvent&) { - if (m_game_over_animation) { + if (m_start_game_over_animation_next_frame) { + m_start_game_over_animation_next_frame = false; + m_game_over_animation = true; + } else if (m_game_over_animation) { VERIFY(!m_animation.card().is_null()); if (m_animation.card()->position().x() >= Game::width || m_animation.card()->rect().right() <= 0) create_new_animation_card(); @@ -76,7 +79,11 @@ void Game::start_game_over_animation() return; create_new_animation_card(); - m_game_over_animation = true; + + // We wait one frame, to make sure that the foundation stacks are repainted before we start. + // Otherwise, if the game ended from an attempt_to_move_card_to_foundations() move, the + // foundations could appear empty or otherwise incorrect. + m_start_game_over_animation_next_frame = true; start_timer(s_timer_interval_ms); @@ -322,10 +329,10 @@ void Game::doubleclick_event(GUI::MouseEvent& event) void Game::check_for_game_over() { - for (auto& stack : m_stacks) { - if (stack.type() != CardStack::Type::Foundation) - continue; - if (stack.count() != Card::card_count) + for (auto foundationID : foundations) { + auto& foundation = stack(foundationID); + + if (foundation.count() != Card::card_count) return; } @@ -447,8 +454,12 @@ bool Game::attempt_to_move_card_to_foundations(CardStack& from) } } - if (card_was_moved && (from.type() == CardStack::Type::Play)) - pop_waste_to_play_stack(); + if (card_was_moved) { + if (from.type() == CardStack::Type::Play) + pop_waste_to_play_stack(); + + check_for_game_over(); + } return card_was_moved; } diff --git a/Userland/Games/Solitaire/Game.h b/Userland/Games/Solitaire/Game.h index 9dfcff24a2..07dc7f8d49 100644 --- a/Userland/Games/Solitaire/Game.h +++ b/Userland/Games/Solitaire/Game.h @@ -198,6 +198,7 @@ private: bool m_mouse_down { false }; Animation m_animation; + bool m_start_game_over_animation_next_frame { false }; bool m_game_over_animation { false }; bool m_waiting_for_new_game { true }; bool m_new_game_animation { false };