diff --git a/include/gamestate.hpp b/include/gamestate.hpp index 13c6765..48f799c 100755 --- a/include/gamestate.hpp +++ b/include/gamestate.hpp @@ -13,27 +13,25 @@ namespace snakeplusplus { public: GameEngine(); - void SetGameSettings(int argc, char* argv[]); void StartGame(void); sf::Vector2f GetGameBoundaries(void); protected: ; private: std::vector< std::vector > gameBoard; - std::unique_ptr graphics; + PlayerInput controls; + PlayerOutput graphics; Snake player; Food playerFood; - Input playerInput; bool useSFML = 1; bool isGameOver = 0; - void ApplySettings(void); void DisplayEndScreen(void); void GameLoop(void); + sf::Vector2f MovePlayer(void); void PlaceNewSnakePart(sf::Vector2f location); - void PlayerWantsToContinue(void); void RegenerateFood(void); - void ResetGameBoard(void); - void RestartGame(void); + void PrepareGameBoard(void); + void UpdatePlayerSpeed(); }; } diff --git a/include/playerinterface.hpp b/include/playerinterface.hpp index a168c4f..88665fb 100755 --- a/include/playerinterface.hpp +++ b/include/playerinterface.hpp @@ -8,10 +8,10 @@ const int kGridSize = 25; namespace snakeplusplus { - class Input + class PlayerInput { public: - Input(void); + PlayerInput(void); PlayerDirection GetPlayerInput(void); protected: ; @@ -19,56 +19,28 @@ namespace snakeplusplus PlayerDirection lastPlayerInput; }; - class DisplayInterface + class PlayerOutput { public: sf::Vector2f gameBoundaries; - DisplayInterface(void); + PlayerOutput(void); bool IsOpen(void); - virtual void CheckContinue(void) = 0; - virtual void DisplayGameState(std::vector< std::vector >* gameBoard) = 0; - virtual void DisplayEndScreen(void) = 0; - virtual void StartGameWindow(void) = 0; - protected: - bool isWindowAlive; - sf::Time delay = sf::milliseconds(120); - private: - ; - }; - - class CommandLine : public DisplayInterface - { - public: - CommandLine(void); void CheckContinue(void); void DisplayGameState(std::vector< std::vector >* gameBoard); - void DisplayEndScreen(void); void StartGameWindow(void); protected: ; - private: - void Clear(void); - }; - - class SFML : public DisplayInterface - { - public: - SFML(void); - void CheckContinue(void); - void DisplayGameState(std::vector< std::vector >* gameBoard); - void DisplayEndScreen(void); - void StartGameWindow(void); - void UpdateResolution(sf::Vector2i newResolution); - protected: - ; private: void CheckWindowEvents(void); + void DisplayEndScreen(void); void DrawEmpty(sf::Vector2f location); void DrawFood(sf::Vector2f location); void DrawSnake(sf::Vector2f location); sf::RenderWindow gameWindow; sf::VideoMode gameVideoSettings; sf::RectangleShape drawObject; + bool isWindowAlive; + sf::Time delay = sf::milliseconds(120); }; } diff --git a/include/snake.hpp b/include/snake.hpp index 9a58fb2..01b4365 100755 --- a/include/snake.hpp +++ b/include/snake.hpp @@ -2,47 +2,38 @@ #ifndef SNAKE_HPP #define SNAKE_HPP +#include #include #include #include #include -#include "common.hpp" namespace snakeplusplus { - class Snake + struct Snake { public: Snake(void); - PlayerDirection GetDirection(void); - sf::Vector2f GetHeadLocation(void); - sf::Vector2f Move(void); + sf::Vector2f headLocation; + sf::Vector2f speed; + std::queue< std::shared_ptr > body; void Pop(void); - sf::Vector2f Reset(void); - void UpdateDirection(PlayerDirection newDirection); protected: ; private: - std::queue< std::shared_ptr > snakeBody; - PlayerDirection direction = kNone; - sf::Vector2f headLocation; - void MoveLeft(void); - void MoveUp(void); - void MoveDown(void); - void MoveRight(void); + ; }; - class Food + struct Food { public: - Food(); + Food(void); + sf::Vector2f location; + std::shared_ptr food; void GenerateNewFood(sf::Vector2f boundaries); - sf::Vector2f GetFoodLocation(void); protected: ; private: - std::shared_ptr food; - sf::Vector2f location; std::default_random_engine generator; int GenerateRandomNumber(int generationLimit); }; diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 26fa424..6cc60d8 100755 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -1,4 +1,5 @@ // GameState.cpp +#include #include #include #include @@ -14,62 +15,37 @@ namespace snakeplusplus return; } - void GameEngine::SetGameSettings(int argc, char* argv[]) - { - std::string convertedString; - for (int i = 0; i < argc; i++) - { - convertedString = argv[i]; - if (convertedString == "--no-sfml") - useSFML = false; - } - } - void GameEngine::StartGame() { - ApplySettings(); - ResetGameBoard(); - graphics->StartGameWindow(); + //ApplySettings(); + PrepareGameBoard(); + graphics.StartGameWindow(); GameLoop(); return; } - void GameEngine::ApplySettings(void) - { - if (useSFML) - graphics.reset(new SFML()); - else - graphics.reset(new CommandLine()); - return; - } - - // TODO: Reimplement for DisplayInterface - void GameEngine::DisplayEndScreen(void) - { - graphics->DisplayEndScreen(); - return; - } - void GameEngine::GameLoop(void) { sf::Vector2f newHeadPosition; - while (graphics->IsOpen()) + while (graphics.IsOpen()) { - // player.UpdateDirection(playerInput.GetPlayerInput()); - // newHeadPosition = player.Move(); - // if (playerFood.GetFoodLocation() != newHeadPosition) - // player.Pop(); - // PlaceNewSnakePart(newHeadPosition); - graphics->DisplayGameState(&gameBoard); - // if (isGameOver) - // PlayerWantsToContinue(); + UpdatePlayerSpeed(); + PlaceNewSnakePart(MovePlayer()); + graphics.DisplayGameState(&gameBoard); } return; } + sf::Vector2f GameEngine::MovePlayer(void) + { + sf::Vector2f newHeadPosition; + newHeadPosition.x = player.headLocation.x + player.speed.x; + newHeadPosition.y = player.headLocation.y + player.speed.y; + return newHeadPosition; + } sf::Vector2f GameEngine::GetGameBoundaries(void) { - return graphics->gameBoundaries; + return graphics.gameBoundaries; } void GameEngine::PlaceNewSnakePart(sf::Vector2f location) @@ -80,8 +56,8 @@ namespace snakeplusplus locationState = gameBoard.at(location.y).at(location.x); if (locationState == 'O') isGameOver = true; // Game should end (Snake touching snake) - if (locationState == ' ') - player.Pop(); // Snake shouldn't extend + if (playerFood.location != location) + player.Pop(); gameBoard.at(location.y).at(location.x) = 'O'; } catch (const std::out_of_range& error) { isGameOver = true; // Snake ran into edge @@ -90,40 +66,57 @@ namespace snakeplusplus return; } - void GameEngine::PlayerWantsToContinue(void) - { - graphics->CheckContinue(); - return; - } - // Generates new food until not colliding with player void GameEngine::RegenerateFood(void) { - sf::Vector2f newLocation = playerFood.GetFoodLocation(); + sf::Vector2f newLocation = playerFood.location; bool isUpdated = false; // Keep making new food until generating a valid spot while (gameBoard.at(newLocation.y).at(newLocation.x) == 'O') { isUpdated = true; playerFood.GenerateNewFood(GetGameBoundaries()); - newLocation = playerFood.GetFoodLocation(); + newLocation = playerFood.location; } if (isUpdated) gameBoard.at(newLocation.y).at(newLocation.x) = 'X'; return; } - void GameEngine::ResetGameBoard(void) + void GameEngine::PrepareGameBoard(void) { gameBoard.clear(); sf::Vector2f boardDimensions = GetGameBoundaries(); std::vector tempBoard; tempBoard.resize(boardDimensions.x, ' '); gameBoard.resize(boardDimensions.y, tempBoard); - PlaceNewSnakePart(player.Reset()); - // playerFood.GenerateNewFood(boardDimensions); - // sf::Vector2f foodStartLocation = playerFood.GetFoodLocation(); - // gameBoard.at(foodStartLocation.y).at(foodStartLocation.x) = 'X'; - // return; + sf::Vector2f playerLocation(4,5); + char* headLocation = &gameBoard.at(playerLocation.y).at(playerLocation.x); + *headLocation = 'O'; + player.body.push(std::shared_ptr(headLocation)); + sf::Vector2f foodLocation(2,2); + gameBoard.at(foodLocation.y).at(foodLocation.x) = 'X'; + return; + } + + void GameEngine::UpdatePlayerSpeed(void) + { + PlayerDirection input = controls.GetPlayerInput(); + switch (input) { + case kUp: + player.speed.x = 0; + player.speed.y = 1; + case kLeft: + player.speed.x = -1; + player.speed.y = 0; + case kRight: + player.speed.x = 1; + player.speed.y = 0; + case kDown: + player.speed.x = 0; + player.speed.y = -1; + default: + break; + } } } diff --git a/src/main.cpp b/src/main.cpp index 74082b6..854534f 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,7 @@ #include "gamestate.hpp" -int main(int argc, char *argv[]) +int main(void) { snakeplusplus::GameEngine game; - game.SetGameSettings(argc, argv); game.StartGame(); } diff --git a/src/playerinterface.cpp b/src/playerinterface.cpp index 00bc9d5..f4a5b78 100755 --- a/src/playerinterface.cpp +++ b/src/playerinterface.cpp @@ -3,12 +3,12 @@ namespace snakeplusplus { - Input::Input(void) + PlayerInput::PlayerInput(void) { lastPlayerInput = kNone; } - PlayerDirection Input::GetPlayerInput(void) + PlayerDirection PlayerInput::GetPlayerInput(void) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) lastPlayerInput = kLeft; @@ -21,69 +21,12 @@ namespace snakeplusplus return lastPlayerInput; } - DisplayInterface::DisplayInterface(void) - { - return; - } - - bool DisplayInterface::IsOpen(void) + bool PlayerOutput::IsOpen(void) { return isWindowAlive; } - CommandLine::CommandLine(void) - { - gameBoundaries.x = 1025 / kGridSize; - gameBoundaries.y = 725 / kGridSize; - return; - } - - void CommandLine::CheckContinue(void) - { - int placeholder; - std::cout << "Press enter to play again."; - std::cin >> placeholder; - return; - } - - void CommandLine::DisplayEndScreen(void) - { - std::cout << "Game Over!" << std::endl; - return; - } - - void CommandLine::DisplayGameState(std::vector< std::vector >* gameBoard) - { - Clear(); - for (int i = 0; i < gameBoundaries.y; i++) - { - for (int j = 0; j < gameBoundaries.x; j++) - std::cout << gameBoard->at(i).at(j); - std::cout << std::endl; - } - sf::sleep(delay); - } - - void CommandLine::StartGameWindow(void) - { - isWindowAlive = true; - return; - } - - void CommandLine::Clear(void) - { - #if defined _WIN32 - system("cls"); - //clrscr(); // including header file : conio.h - #elif defined (__LINUX__) || defined(__gnu_linux__) || defined(__linux__) - system("clear"); - //std::cout<< u8"\033[2J\033[1;1H"; //Using ANSI Escape Sequences - #elif defined (__APPLE__) - system("clear"); - #endif - } - - SFML::SFML(void) + PlayerOutput::PlayerOutput(void) { float kWidth = 1025 / kGridSize; float kHeight = 725 / kGridSize; @@ -93,7 +36,7 @@ namespace snakeplusplus return; } - void SFML::CheckContinue(void) + void PlayerOutput::CheckContinue(void) { sf::Event event; while (true) @@ -111,7 +54,7 @@ namespace snakeplusplus } } - void SFML::DisplayEndScreen(void) + void PlayerOutput::DisplayEndScreen(void) { gameWindow.clear(); sf::Vector2f textPosition(gameBoundaries); @@ -131,7 +74,7 @@ namespace snakeplusplus return; } - void SFML::DisplayGameState(std::vector< std::vector >* gameBoard) + void PlayerOutput::DisplayGameState(std::vector< std::vector >* gameBoard) { CheckWindowEvents(); sf::Vector2i location(0,0); @@ -154,24 +97,14 @@ namespace snakeplusplus return; } - void SFML::StartGameWindow(void) + void PlayerOutput::StartGameWindow(void) { gameWindow.create(gameVideoSettings, "SnakePlusPlus"); isWindowAlive = true; return; } - void SFML::UpdateResolution(sf::Vector2i newResolution) - { - gameVideoSettings.width = newResolution.x; - gameVideoSettings.height = newResolution.y; - gameBoundaries.x = gameVideoSettings.width / kGridSize; - gameBoundaries.y = gameVideoSettings.height / kGridSize; - gameWindow.create(gameVideoSettings, "SnakePlusPlus"); - return; - } - - void SFML::CheckWindowEvents(void) + void PlayerOutput::CheckWindowEvents(void) { sf::Event event; while (gameWindow.pollEvent(event)) @@ -182,7 +115,7 @@ namespace snakeplusplus } } - void SFML::DrawEmpty(sf::Vector2f location) + void PlayerOutput::DrawEmpty(sf::Vector2f location) { location *= static_cast(kGridSize); drawObject.setPosition(location); @@ -191,7 +124,7 @@ namespace snakeplusplus return; } - void SFML::DrawFood(sf::Vector2f location) + void PlayerOutput::DrawFood(sf::Vector2f location) { location *= static_cast(kGridSize); drawObject.setPosition(location); @@ -200,7 +133,7 @@ namespace snakeplusplus return; } - void SFML::DrawSnake(sf::Vector2f location) + void PlayerOutput::DrawSnake(sf::Vector2f location) { location *= static_cast(kGridSize); drawObject.setPosition(location); diff --git a/src/snake.cpp b/src/snake.cpp index a53a8af..b4f3ce5 100755 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -1,8 +1,8 @@ // Snake.cpp +#include #include #include #include -#include "common.hpp" #include "snake.hpp" namespace snakeplusplus @@ -12,68 +12,11 @@ namespace snakeplusplus { return; } - - PlayerDirection Snake::GetDirection(void) - { - return direction; - } - - sf::Vector2f Snake::GetHeadLocation(void) - { - return headLocation; - } - - // Update snake with location information - sf::Vector2f Snake::Move(void) - { - if (direction == kLeft) MoveLeft(); - if (direction == kUp) MoveUp(); - if (direction == kDown) MoveDown(); - if (direction == kRight) MoveRight(); - return headLocation; - } - - // Removes tail of snake + void Snake::Pop(void) { - *(snakeBody.front().get()) = ' '; - snakeBody.pop(); - return; - } - - sf::Vector2f Snake::Reset(void) - { - return sf::Vector2f(4,5); - } - - void Snake::UpdateDirection(PlayerDirection newDirection) - { - direction = newDirection; - return; - } - - void Snake::MoveLeft(void) - { - headLocation.x -= 1; - return; - } - - void Snake::MoveUp(void) - { - headLocation.y -= 1; - return; - } - - void Snake::MoveDown(void) - { - headLocation.y += 1; - return; - } - - void Snake::MoveRight(void) - { - headLocation.x += 1; - return; + *(body.front().get()) = ' '; + body.pop(); } Food::Food() @@ -88,11 +31,6 @@ namespace snakeplusplus location.y = GenerateRandomNumber(boundaries.y); } - sf::Vector2f Food::GetFoodLocation(void) - { - return location; - } - // Returns a newly generated number int Food::GenerateRandomNumber(int generationLimit) {