summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitrii Ubskii <ubskydm@gmail.com>2021-06-11 15:28:42 +0300
committerAndreas Kling <kling@serenityos.org>2021-06-11 22:45:14 +0200
commit9ce5ce3560d9825340f58445f54df5b81a514255 (patch)
treedd9382862a174be9a888e67588d37fc8a17792ee
parent30c831a3bee41dd7ab0a5908e1ba6940f1a15da7 (diff)
downloadserenity-9ce5ce3560d9825340f58445f54df5b81a514255.zip
2048: Add pop-in animation for newly added tiles
-rw-r--r--Userland/Games/2048/BoardView.cpp32
-rw-r--r--Userland/Games/2048/BoardView.h7
-rw-r--r--Userland/Games/2048/Game.h13
3 files changed, 47 insertions, 5 deletions
diff --git a/Userland/Games/2048/BoardView.cpp b/Userland/Games/2048/BoardView.cpp
index b0b3925955..e81d6b501b 100644
--- a/Userland/Games/2048/BoardView.cpp
+++ b/Userland/Games/2048/BoardView.cpp
@@ -21,6 +21,12 @@ BoardView::~BoardView()
void BoardView::set_board(Game::Board const* board)
{
+ if (has_timer())
+ stop_timer();
+
+ pop_in_animation_frame = 0;
+ start_timer(frame_duration_ms);
+
if (m_board == board)
return;
@@ -56,6 +62,8 @@ void BoardView::pick_font()
auto font = font_database.get_by_name(best_font_name);
set_font(font);
+
+ m_min_cell_size = best_font_size;
}
size_t BoardView::rows() const
@@ -157,6 +165,16 @@ Gfx::Color BoardView::text_color_for_cell(u32 value)
return Color::from_rgb(0xf9f6f2);
}
+void BoardView::timer_event(Core::TimerEvent&)
+{
+ if (pop_in_animation_frame < animation_duration) {
+ pop_in_animation_frame++;
+ update();
+ if (pop_in_animation_frame == animation_duration)
+ stop_timer();
+ }
+}
+
void BoardView::paint_event(GUI::PaintEvent& event)
{
Frame::paint_event(event);
@@ -185,12 +203,16 @@ void BoardView::paint_event(GUI::PaintEvent& event)
for (size_t column = 0; column < columns(); ++column) {
for (size_t row = 0; row < rows(); ++row) {
- auto rect = Gfx::IntRect {
- field_rect.x() + m_padding + (m_cell_size + m_padding) * column,
- field_rect.y() + m_padding + (m_cell_size + m_padding) * row,
- m_cell_size,
- m_cell_size,
+ auto center = Gfx::IntPoint {
+ field_rect.x() + m_padding + (m_cell_size + m_padding) * column + m_cell_size / 2,
+ field_rect.y() + m_padding + (m_cell_size + m_padding) * row + m_cell_size / 2,
};
+ auto tile_size = Gfx::IntSize { m_cell_size, m_cell_size };
+ if (pop_in_animation_frame < animation_duration && Game::Board::Position { row, column } == m_board->last_added_position) {
+ float pop_in_size = m_min_cell_size + (m_cell_size - m_min_cell_size) * (pop_in_animation_frame / (float)animation_duration);
+ tile_size = Gfx::IntSize { pop_in_size, pop_in_size };
+ }
+ auto rect = Gfx::IntRect::centered_on(center, tile_size);
auto entry = tiles[row][column];
painter.fill_rect(rect, background_color_for_cell(entry));
if (entry > 0)
diff --git a/Userland/Games/2048/BoardView.h b/Userland/Games/2048/BoardView.h
index 20db43b15b..41d79a47df 100644
--- a/Userland/Games/2048/BoardView.h
+++ b/Userland/Games/2048/BoardView.h
@@ -24,6 +24,7 @@ private:
virtual void resize_event(GUI::ResizeEvent&) override;
virtual void paint_event(GUI::PaintEvent&) override;
virtual void keydown_event(GUI::KeyEvent&) override;
+ virtual void timer_event(Core::TimerEvent&) override;
size_t rows() const;
size_t columns() const;
@@ -35,7 +36,13 @@ private:
Color text_color_for_cell(u32 value);
float m_padding { 0 };
+ float m_min_cell_size { 0 };
float m_cell_size { 0 };
Game::Board const* m_board { nullptr };
+
+ static constexpr int frame_duration_ms = 1000 / 60;
+ static constexpr int animation_duration = 5;
+
+ int pop_in_animation_frame = 0;
};
diff --git a/Userland/Games/2048/Game.h b/Userland/Games/2048/Game.h
index f027a02675..29d8e1854a 100644
--- a/Userland/Games/2048/Game.h
+++ b/Userland/Games/2048/Game.h
@@ -41,10 +41,23 @@ public:
Tiles tiles;
+ struct Position {
+ size_t row;
+ size_t column;
+
+ bool operator==(Position const& other) const
+ {
+ return row == other.row && column == other.column;
+ }
+ };
+
void add_tile(size_t row, size_t column, u32 value)
{
tiles[row][column] = value;
+ last_added_position = Position { row, column };
}
+
+ Position last_added_position { 0, 0 };
};
Board const& board() const { return m_board; }