diff options
| -rwxr-xr-x | main | bin | 505752 -> 511712 bytes | |||
| -rw-r--r-- | main.cpp | 115 | ||||
| -rw-r--r-- | terminal-game-utils.hpp | 2 |
3 files changed, 98 insertions, 19 deletions
| Binary files differ @@ -41,6 +41,8 @@ class Snake { const int WIDTH, HEIGHT, STARTING_DELAY, MAX_SPEED; const double ACCELERATION = 0; + std::mutex mKeyMutex; + mSnakeUnit mLastDequeued; mSnakeUnit mApple; @@ -54,7 +56,8 @@ class Snake { char mSnakeDirection = 'r'; int mApplesAte = 0; - bool mRunning = true; + bool mGameNotOver = true; + bool mPaused = false; std::string mRepeat(int times, std::string str) { std::string returned; @@ -169,22 +172,22 @@ class Snake { return ' '; } - void mSetSnakeDirection() { - tgu::GameKey popped = mKeyQueue.front(); - mKeyQueue.pop(); - + void mHandleGameInput(tgu::GameKey input) { char PotentialSnakeDirection; - if (popped == tgu::GameKey::W || popped == tgu::GameKey::UPARROW) + if (input == tgu::GameKey::W || input == tgu::GameKey::UPARROW) PotentialSnakeDirection = 'u'; - else if (popped == tgu::GameKey::A || popped == tgu::GameKey::LEFTARROW) + else if (input == tgu::GameKey::A || input == tgu::GameKey::LEFTARROW) PotentialSnakeDirection = 'l'; - else if (popped == tgu::GameKey::S || popped == tgu::GameKey::DOWNARROW) + else if (input == tgu::GameKey::S || input == tgu::GameKey::DOWNARROW) PotentialSnakeDirection = 'd'; - else if (popped == tgu::GameKey::D || - popped == tgu::GameKey::RIGHTARROW) { + else if (input == tgu::GameKey::D || + input == tgu::GameKey::RIGHTARROW) { PotentialSnakeDirection = 'r'; - } else if (popped == tgu::GameKey::Q) { + } else if (input == tgu::GameKey::ESCAPE || input == tgu::GameKey::P) { + mPaused = true; + return; + } else if (input == tgu::GameKey::Q) { tgu::ClearTerminal(); tgu::MoveCursor(0, 0); exit(0); @@ -197,6 +200,24 @@ class Snake { mSnakeDirection = PotentialSnakeDirection; } + void mHandlePausedInput(tgu::GameKey input) { + if (input == tgu::GameKey::P || input == tgu::GameKey::ESCAPE) + mPaused = false; + + if (input == tgu::GameKey::Q) + mGameNotOver = false; + } + + void mHandleInput() { + tgu::GameKey popped = mKeyQueue.front(); + mKeyQueue.pop(); + + if (mPaused) + mHandlePausedInput(popped); + else + mHandleGameInput(popped); + } + std::tuple<int, int> mGetDirectionOffset(char c) { tgu::MoveCursor(30, 30); if (c == 'l') @@ -248,7 +269,7 @@ class Snake { if (PotentialX <= -1 || PotentialY <= -1 || PotentialX >= WIDTH || PotentialY >= HEIGHT || IsInSnake(PotentialX, PotentialY)) { if (mGraceFrames <= 0) { - mRunning = false; + mGameNotOver = false; mDie(); } else { mGraceFrames = 0; @@ -284,19 +305,25 @@ class Snake { } void mGameTick() { + mKeyMutex.lock(); if (mKeyQueue.size() != 0) { - mSetSnakeDirection(); + mHandleInput(); } + mKeyMutex.unlock(); - mSnakeStep(); + if (!mPaused) + mSnakeStep(); } void mInputLoop() { tgu::GameKey key; - while (mRunning) { + while (mGameNotOver) { key = tgu::GetKeyPress(); - if (mKeyQueue.size() <= 2) + if (mKeyQueue.size() <= 2) { + mKeyMutex.lock(); mKeyQueue.push(key); + mKeyMutex.unlock(); + } } } @@ -370,7 +397,7 @@ class Snake { } void mGameLoop() { - while (mRunning) { + while (mGameNotOver) { int CalculatedDelay = STARTING_DELAY - (mApplesAte * ACCELERATION); int TickDelay = CalculatedDelay >= MAX_SPEED ? CalculatedDelay : MAX_SPEED; @@ -433,9 +460,61 @@ class Snake { mGameLoop(); } + + static void SinglePrompt(std::string prompt, int &val) { + std::string sTmp; + int iTmp = 0; + + tgu::ClearTerminal(); + tgu::MoveCursor(0, 0); + std::cout << prompt; + tgu::TextRGB(144, 144, 144); + std::cout << val; + tgu::MoveCursor(0, prompt.size()); + tgu::TerminalColorReset(); + + try { + std::getline(std::cin, sTmp); + iTmp = std::stoi(sTmp); + if (iTmp <= val) + iTmp = val; + + } catch (const std::exception &e) { + iTmp = val; + std::cout << e.what() << '\n'; + } + val = iTmp; + } + + static GameSettings SettingsPrompt() { + int width = 14; + int height = 14; + int startingdelay = 400; + int maxspeed = 200; + int acceleration = 10; + std::string prompt; + + tgu::EnterGameBuffer(); + + SinglePrompt("Width: ", width); + SinglePrompt("Height: ", height); + SinglePrompt("Starting delay: ", startingdelay); + SinglePrompt("Max speed: ", maxspeed); + SinglePrompt("Acceleration: ", acceleration); + + tgu::LeaveGameBuffer(); + + GameSettings settings = {.width = width, + .height = height, + .startingdelay = startingdelay, + .maxspeed = maxspeed, + .acceleration = acceleration}; + + return settings; + } }; int main() { - Snake hi({.startingdelay = 100}); + Snake hi(Snake::SettingsPrompt()); hi.StartGame(); } diff --git a/terminal-game-utils.hpp b/terminal-game-utils.hpp index aa540bb..1fdcf13 100644 --- a/terminal-game-utils.hpp +++ b/terminal-game-utils.hpp @@ -119,7 +119,7 @@ inline void EnableRawMode() { raw.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON); raw.c_oflag &= ~(OPOST); raw.c_cflag |= (CS8); - raw.c_lflag &= ~(ECHO | ICANON | IEXTEN); + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; |
