mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-31 23:22:03 +03:00
Snake: Use a queue for the movement inputs.
This makes it a lot less finicky to make rapid moves like staircasing and sudden turns.
This commit is contained in:
parent
e24e486714
commit
b41e95b578
Notes:
sideshowbarker
2024-07-19 14:39:03 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/b41e95b5781
@ -39,6 +39,9 @@ public:
|
||||
|
||||
const T& at(int index) const { return m_elements[(m_head + index) % Capacity]; }
|
||||
|
||||
const T& first() const { return at(0); }
|
||||
const T& last() const { return at(size() - 1); }
|
||||
|
||||
class ConstIterator {
|
||||
public:
|
||||
bool operator!=(const ConstIterator& other) { return m_index != other.m_index; }
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user