diff --git a/Userland/Games/Hearts/Game.cpp b/Userland/Games/Hearts/Game.cpp index 3c921e9d0b5..a968fde40f6 100644 --- a/Userland/Games/Hearts/Game.cpp +++ b/Userland/Games/Hearts/Game.cpp @@ -402,6 +402,11 @@ void Game::advance_game() if (m_animation_playing) return; + if (m_inverted_card) { + m_inverted_card->set_inverted(false); + m_inverted_card.clear(); + } + if (m_state == State::Play && game_ended()) { m_state = State::GameEnded; on_status_change("Game ended."); @@ -638,6 +643,11 @@ void Game::card_clicked_during_play(size_t card_index, Card& card) { String explanation; if (!is_valid_play(m_players[0], card, &explanation)) { + if (m_inverted_card) + m_inverted_card->set_inverted(false); + card.set_inverted(true); + m_inverted_card = card; + update(); on_status_change(String::formatted("You can't play this card: {}", explanation)); continue_game_after_delay(); return; diff --git a/Userland/Games/Hearts/Game.h b/Userland/Games/Hearts/Game.h index c21beb37a9f..c54fbf21bcf 100644 --- a/Userland/Games/Hearts/Game.h +++ b/Userland/Games/Hearts/Game.h @@ -106,6 +106,8 @@ private: int m_animation_current_step { 0 }; int m_animation_steps { 0 }; OwnPtr> m_animation_did_finish; + + RefPtr m_inverted_card; }; } diff --git a/Userland/Libraries/LibCards/Card.cpp b/Userland/Libraries/LibCards/Card.cpp index fe8699234bc..1ac31c80823 100644 --- a/Userland/Libraries/LibCards/Card.cpp +++ b/Userland/Libraries/LibCards/Card.cpp @@ -60,6 +60,7 @@ static const NonnullRefPtr s_club = Gfx::CharacterBitmap:: 11, 9); static RefPtr s_background; +static RefPtr s_background_inverted; Card::Card(Type type, uint8_t value) : m_rect(Gfx::IntRect({}, { width, height })) @@ -85,6 +86,8 @@ Card::Card(Type type, uint8_t value) { { (width - target_size.width()) / 2, (height - target_size.height()) / 2 }, target_size }, *image, image->rect()); bg_painter.draw_rect(paint_rect, Color::Black); + + s_background_inverted = invert_bitmap(*s_background); } Gfx::Painter painter(m_front); @@ -126,6 +129,8 @@ Card::Card(Type type, uint8_t value) m_front->set_pixel(x, y, m_front->get_pixel(width - x - 1, height - y - 1)); } } + + m_front_inverted = invert_bitmap(*m_front); } Card::~Card() @@ -135,7 +140,10 @@ Card::~Card() void Card::draw(GUI::Painter& painter) const { VERIFY(!s_background.is_null()); - painter.blit(position(), m_upside_down ? *s_background : *m_front, m_front->rect()); + if (m_inverted) + painter.blit(position(), m_upside_down ? *s_background_inverted : *m_front_inverted, m_front_inverted->rect()); + else + painter.blit(position(), m_upside_down ? *s_background : *m_front, m_front->rect()); } void Card::clear(GUI::Painter& painter, const Color& background_color) const @@ -158,4 +166,16 @@ void Card::clear_and_draw(GUI::Painter& painter, const Color& background_color) save_old_position(); } +NonnullRefPtr Card::invert_bitmap(Gfx::Bitmap& bitmap) +{ + auto inverted_bitmap = bitmap.clone(); + VERIFY(inverted_bitmap); + for (int y = 0; y < inverted_bitmap->height(); y++) { + for (int x = 0; x < inverted_bitmap->width(); x++) { + inverted_bitmap->set_pixel(x, y, inverted_bitmap->get_pixel(x, y).inverted()); + } + } + return *inverted_bitmap; +} + } diff --git a/Userland/Libraries/LibCards/Card.h b/Userland/Libraries/LibCards/Card.h index 4c9c7ef8a6c..eaafe688632 100644 --- a/Userland/Libraries/LibCards/Card.h +++ b/Userland/Libraries/LibCards/Card.h @@ -46,11 +46,13 @@ public: bool is_old_position_valid() const { return m_old_position_valid; } bool is_moving() const { return m_moving; } bool is_upside_down() const { return m_upside_down; } + bool is_inverted() const { return m_inverted; } Gfx::Color color() const { return (m_type == Diamonds || m_type == Hearts) ? Color::Red : Color::Black; } void set_position(const Gfx::IntPoint p) { m_rect.set_location(p); } void set_moving(bool moving) { m_moving = moving; } void set_upside_down(bool upside_down) { m_upside_down = upside_down; } + void set_inverted(bool inverted) { m_inverted = inverted; } void save_old_position(); @@ -61,14 +63,18 @@ public: private: Card(Type type, uint8_t value); + static NonnullRefPtr invert_bitmap(Gfx::Bitmap&); + Gfx::IntRect m_rect; NonnullRefPtr m_front; + RefPtr m_front_inverted; Gfx::IntPoint m_old_position; Type m_type; uint8_t m_value; bool m_old_position_valid { false }; bool m_moving { false }; bool m_upside_down { false }; + bool m_inverted { false }; }; }