Hearts: Highlight cards when an invalid play is attempted

This briefly inverts the selected card when the user attempts to make
an invalid play.
This commit is contained in:
Gunnar Beutner 2021-05-26 09:22:19 +02:00 committed by Andreas Kling
parent 2c772d1848
commit 971f4ca71c
Notes: sideshowbarker 2024-07-18 17:21:46 +09:00
4 changed files with 39 additions and 1 deletions

View file

@ -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;

View file

@ -106,6 +106,8 @@ private:
int m_animation_current_step { 0 };
int m_animation_steps { 0 };
OwnPtr<Function<void()>> m_animation_did_finish;
RefPtr<Card> m_inverted_card;
};
}

View file

@ -60,6 +60,7 @@ static const NonnullRefPtr<Gfx::CharacterBitmap> s_club = Gfx::CharacterBitmap::
11, 9);
static RefPtr<Gfx::Bitmap> s_background;
static RefPtr<Gfx::Bitmap> 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<Gfx::Bitmap> 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;
}
}

View file

@ -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<Gfx::Bitmap> invert_bitmap(Gfx::Bitmap&);
Gfx::IntRect m_rect;
NonnullRefPtr<Gfx::Bitmap> m_front;
RefPtr<Gfx::Bitmap> 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 };
};
}