diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-20 03:44:01 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-20 03:44:56 +0200 |
commit | b41e95b57812ec498842410068ef11676aaa9a4d (patch) | |
tree | c2260626c915464e00c66849f237af60e21d79fd /Games | |
parent | e24e4867142d1ae2a495060fa07629f941e8e4ee (diff) | |
download | serenity-b41e95b57812ec498842410068ef11676aaa9a4d.zip |
Snake: Use a queue for the movement inputs.
This makes it a lot less finicky to make rapid moves like staircasing and
sudden turns.
Diffstat (limited to 'Games')
-rw-r--r-- | Games/Snake/SnakeGame.cpp | 45 | ||||
-rw-r--r-- | Games/Snake/SnakeGame.h | 15 |
2 files changed, 40 insertions, 20 deletions
diff --git a/Games/Snake/SnakeGame.cpp b/Games/Snake/SnakeGame.cpp index a0ed4175ad..d3a1b139a9 100644 --- a/Games/Snake/SnakeGame.cpp +++ b/Games/Snake/SnakeGame.cpp @@ -56,11 +56,13 @@ void SnakeGame::timer_event(CTimerEvent&) if (m_tail.size() > m_length) m_tail.take_last(); - m_head.row += m_vertical_velocity; - m_head.column += m_horizontal_velocity; + if (!m_velocity_queue.is_empty()) + m_velocity = m_velocity_queue.dequeue(); - m_last_vertical_velocity = m_vertical_velocity; - m_last_horizontal_velocity = m_horizontal_velocity; + m_head.row += m_velocity.vertical; + m_head.column += m_velocity.horizontal; + + m_last_velocity = m_velocity; if (m_head.row >= m_rows) m_head.row = 0; @@ -90,31 +92,27 @@ void SnakeGame::keydown_event(GKeyEvent& event) switch (event.key()) { case KeyCode::Key_A: case KeyCode::Key_Left: - if (m_last_horizontal_velocity == 1) + if (last_velocity().horizontal == 1) break; - m_vertical_velocity = 0; - m_horizontal_velocity = -1; + queue_velocity(0, -1); break; case KeyCode::Key_D: case KeyCode::Key_Right: - if (m_last_horizontal_velocity == -1) + if (last_velocity().horizontal == -1) break; - m_vertical_velocity = 0; - m_horizontal_velocity = 1; + queue_velocity(0, 1); break; case KeyCode::Key_W: case KeyCode::Key_Up: - if (m_last_vertical_velocity == 1) + if (last_velocity().vertical == 1) break; - m_vertical_velocity = -1; - m_horizontal_velocity = 0; + queue_velocity(-1, 0); break; case KeyCode::Key_S: case KeyCode::Key_Down: - if (m_last_vertical_velocity == -1) + if (last_velocity().vertical == -1) break; - m_vertical_velocity = 1; - m_horizontal_velocity = 0; + queue_velocity(1, 0); break; default: break; @@ -149,3 +147,18 @@ void SnakeGame::game_over() { reset(); } + +void SnakeGame::queue_velocity(int v, int h) +{ + if (last_velocity().vertical == v && last_velocity().horizontal == h) + return; + m_velocity_queue.enqueue({ v, h }); +} + +const SnakeGame::Velocity& SnakeGame::last_velocity() const +{ + if (!m_velocity_queue.is_empty()) + return m_velocity_queue.last(); + + return m_last_velocity; +} diff --git a/Games/Snake/SnakeGame.h b/Games/Snake/SnakeGame.h index 2e8d04c00d..20c926ff70 100644 --- a/Games/Snake/SnakeGame.h +++ b/Games/Snake/SnakeGame.h @@ -1,6 +1,7 @@ #pragma once #include <LibGUI/GWidget.h> +#include <AK/CircularQueue.h> class SnakeGame : public GWidget { public: @@ -24,18 +25,24 @@ private: } }; + struct Velocity { + int vertical { 0 }; + int horizontal { 0 }; + }; + void game_over(); void spawn_fruit(); bool is_available(const Coordinate&); + void queue_velocity(int v, int h); + const Velocity& last_velocity() const; int m_rows { 20 }; int m_columns { 20 }; - int m_horizontal_velocity { 1 }; - int m_vertical_velocity { 0 }; + Velocity m_velocity { 0, 1 }; + Velocity m_last_velocity { 0, 1 }; - int m_last_horizontal_velocity { 1 }; - int m_last_vertical_velocity { 0 }; + CircularQueue<Velocity, 10> m_velocity_queue; Coordinate m_head; Vector<Coordinate> m_tail; |