diff --git a/src/GameState.cpp b/src/GameState.cpp index c293cf6..f9a89a1 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -1,8 +1,7 @@ -// #include +// GameState.cpp #include #include #include "Snake.h" -#include "SnakeFood.h" #include "GameState.h" GameState::GameState() @@ -24,14 +23,10 @@ GameState::GameState(int newHorizontal, int newVertical) void GameState::startNewGame() { gameWindow.create(gameVideoMode, "SnakePlusPlus"); - sf::Time delay = sf::milliseconds(25); + sf::Time delay = sf::milliseconds(100); int snakeDirection = 0; Snake player(sf::Vector2f(25,25)); SnakeFood playerFood(sf::Vector2f(25,25)); - // sf::RectangleShape snakeHead(sf::Vector2f(25,25)); - sf::RectangleShape snakeFood(sf::Vector2f(25,25)); - snakeFood.setFillColor(sf::Color::Red); - snakeFood.setPosition(25,25); while (gameWindow.isOpen()) { @@ -41,15 +36,8 @@ void GameState::startNewGame() if ((event.type == sf::Event::Closed) || (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))) gameWindow.close(); } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) - snakeDirection = 1; - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) - snakeDirection = 2; - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) - snakeDirection = 3; - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) - snakeDirection = 4; - player.MoveSnake(playerFood.snakeFoodObject); + player.CheckDirection(); + player.MoveSnake(playerFood, gameVideoMode); gameWindow.clear(); player.DisplaySnake(gameWindow); gameWindow.draw(playerFood.snakeFoodObject); diff --git a/src/GameState.h b/src/GameState.h index ad8c7bd..f5ccb13 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -2,7 +2,6 @@ #ifndef GAMESTATE_H #define GAMESTATE_H #include -#include class GameState { diff --git a/src/Snake.cpp b/src/Snake.cpp index 8e4887d..d1216cf 100644 --- a/src/Snake.cpp +++ b/src/Snake.cpp @@ -1,22 +1,35 @@ +// Snake.cpp #include +#include #include -#include #include "Snake.h" +#include "SnakeFood.h" -// Test for collision between two objects -bool SnakeCollision(sf::RectangleShape object1, sf::RectangleShape object2) +// Get a new coordinate position based on snake direction +sf::Vector2f CalculateNewPosition(int direction, sf::Vector2f position) +{ + if (direction == 0) + return position; + if (direction == 1) + position.x -= 25; + if (direction == 2) + position.y -= 25; + if (direction == 3) + position.y += 25; + if (direction == 4) + position.x += 25; + return position; +} + +// Test for collision between two object positions +bool GlobalCollision(sf::Vector2f object1Position, sf::Vector2f object2Position) { - // Hack for getting a temporary collision - // Collision only tested for origin corrordinate - sf::Vector2f object1Position = object1.getPosition(); - sf::Vector2f object2Position = object2.getPosition(); if (object1Position.x != object2Position.x) return 0; if (object1Position.y != object2Position.y) return 0; return 1; - } // Check keyboard for new direction of snake @@ -48,26 +61,10 @@ bool Snake::CheckBoundaries() return false; } -// Get a new coordinate position based on snake direction -sf::Vector2f CalculateNewPosition(int direction, sf::Vector2f position) -{ - if (direction == 0) - return position; - if (direction == 1) - position.x -= 25; - if (direction == 2) - position.y -= 25; - if (direction == 3) - position.y += 25; - if (direction == 4) - position.x += 25; - return position; -} - // Move snake based on direction and test for eating food -void Snake::MoveSnake(sf::RectangleShape& snakeFood) +void Snake::MoveSnake(SnakeFood& snakeFood, sf::VideoMode gameVideoMode) { - CheckDirection(); + // CheckDirection(); sf::Vector2f newHeadPosition; newHeadPosition = GetSnakeHeadPosition(); if (CheckBoundaries()) @@ -81,15 +78,9 @@ void Snake::MoveSnake(sf::RectangleShape& snakeFood) } newBodyPart.setFillColor(sf::Color::Green); snakeBody.push_front(newBodyPart); - if (!SnakeCollision(GetSnakeHead(), snakeFood)) + if (!GlobalCollision(GetSnakeHead().getPosition(), snakeFood.snakeFoodObject.getPosition())) snakeBody.pop_back(); - else if (SnakeCollision(GetSnakeHead(), snakeFood)) - { - sf::Vector2f snakeFoodPosition = snakeFood.getPosition(); - snakeFoodPosition.x += 25; - snakeFoodPosition.y += 25; - snakeFood.setPosition(snakeFoodPosition.x, snakeFoodPosition.y); - } + SnakeFoodCollision(snakeFood, gameVideoMode); return; } @@ -124,7 +115,7 @@ bool Snake::IsSelfCollision(sf::RectangleShape testRectangle) { for (auto it = snakeBody.cbegin(); it != snakeBody.cend(); ++it) { - if (SnakeCollision(testRectangle, *it)) + if (GlobalCollision(testRectangle.getPosition(), (*it).getPosition())) { return true; } @@ -132,6 +123,16 @@ bool Snake::IsSelfCollision(sf::RectangleShape testRectangle) return false; } +// If player collides with food then generate until no longer collided with food +void Snake::SnakeFoodCollision(SnakeFood& snakeFood, sf::VideoMode gameVideoMode) +{ + while(IsSelfCollision(snakeFood.snakeFoodObject)) + { + snakeFood.GenerateNewLocation(gameVideoMode.width, gameVideoMode.height); + } + return; +} + // General constructor for snake class Snake::Snake() { diff --git a/src/Snake.h b/src/Snake.h index 27016ed..b7f7a70 100644 --- a/src/Snake.h +++ b/src/Snake.h @@ -1,11 +1,9 @@ // Snake.h #ifndef SNAKE_H #define SNAKE_H -#include -bool SnakeCollision(sf::RectangleShape object1, sf::RectangleShape object2); -int SnakeMovement(); sf::Vector2f CalculateNewPosition(int direction, sf::Vector2f position); +bool GlobalCollision(sf::Vector2f object1Position, sf::Vector2f object2Position); class Snake { @@ -18,7 +16,8 @@ public: sf::Vector2f GetSnakeHeadPosition(); sf::RectangleShape GetSnakeHead(); void DisplaySnake(sf::RenderWindow& window); - void MoveSnake(sf::RectangleShape& snakeFood); + void MoveSnake(SnakeFood& playerFood, sf::VideoMode gameVideoMode); + void SnakeFoodCollision(SnakeFood& snakeFood, sf::VideoMode gameVideoMode); void CheckDirection(); bool CheckBoundaries(); bool IsSelfCollision(sf::RectangleShape testRectangle); diff --git a/src/SnakeFood.cpp b/src/SnakeFood.cpp index 464ea25..4a1dd0f 100644 --- a/src/SnakeFood.cpp +++ b/src/SnakeFood.cpp @@ -1,5 +1,8 @@ -#include +// SnakeFood.cpp +#include +#include #include "SnakeFood.h" +#include "Snake.h" SnakeFood::SnakeFood() { @@ -13,12 +16,26 @@ SnakeFood::SnakeFood(sf::Vector2f snakeFoodSize) snakeFoodObject.setFillColor(sf::Color::Red); } -void SnakeFood::GenerateNewLocation(int maxLocation) +void SnakeFood::GenerateNewLocation(int horizontalLocation, int verticalLocation) { sf::Vector2f newPosition; - std::default_random_engine generator; - std::uniform_int_distribution distribution(0, maxLocation); - newPosition.x = distribution(generator); - newPosition.y = distribution(generator); + newPosition.x = GenerateRandomNumber(horizontalLocation); + newPosition.y = GenerateRandomNumber(verticalLocation); + if (GlobalCollision(snakeFoodObject.getPosition(), newPosition)) + { + std::cout << "Location error: " << newPosition.x << " " << newPosition.y << '\n'; + throw std::runtime_error("Error! New generation on same location"); + } snakeFoodObject.setPosition(newPosition); + return; +} + + +int SnakeFood::GenerateRandomNumber(int generationLimit) +{ + int generatedNumber; + std::uniform_int_distribution<> distribution(0, generationLimit); + generatedNumber = distribution(generator); + generatedNumber -= (generatedNumber % 25); + return generatedNumber; } diff --git a/src/SnakeFood.h b/src/SnakeFood.h index 4c25630..67f603a 100644 --- a/src/SnakeFood.h +++ b/src/SnakeFood.h @@ -1,6 +1,7 @@ // SnakeFood.h #ifndef SNAKEFOOD_H #define SNAKEFOOD_H +#include #include class SnakeFood @@ -8,9 +9,11 @@ class SnakeFood private: public: sf::RectangleShape snakeFoodObject; + std::default_random_engine generator; SnakeFood(); SnakeFood(sf::Vector2f snakeFoodSize); - void GenerateNewLocation(int maxLocation); + void GenerateNewLocation(int horizontalLocation, int verticalLocation); + int GenerateRandomNumber(int generationLimit); }; #endif