summaryrefslogtreecommitdiff
path: root/Games
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-20 03:44:01 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-20 03:44:56 +0200
commitb41e95b57812ec498842410068ef11676aaa9a4d (patch)
treec2260626c915464e00c66849f237af60e21d79fd /Games
parente24e4867142d1ae2a495060fa07629f941e8e4ee (diff)
downloadserenity-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.cpp45
-rw-r--r--Games/Snake/SnakeGame.h15
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;