snakeplusplus/src/Snake.cpp
TriantaTV 2c4537eda7 Fixed generation issue with snakeFood
Fixed generation issue with snakeFood and game should be fully playable without an official end screen implemented. So when the snake gets stuck or the game finishes, there is nothing to close the game automatically.
2022-08-21 02:51:33 -05:00

153 lines
4.1 KiB
C++

// Snake.cpp
#include <iostream>
#include <queue>
#include <SFML\Graphics.hpp>
#include "Snake.h"
#include "SnakeFood.h"
// 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)
{
if (object1Position.x != object2Position.x)
return 0;
if (object1Position.y != object2Position.y)
return 0;
return 1;
}
// Check keyboard for new direction of snake
void Snake::CheckDirection()
{
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;
return;
}
// Check snake head for running into boundaries
bool Snake::CheckBoundaries()
{
if (snakeBody.front().getPosition().x == 0 && snakeDirection == 1)
return true;
if (snakeBody.front().getPosition().y == 0 && snakeDirection == 2)
return true;
// TODO: Change boundaries to not be hard-coded
if (snakeBody.front().getPosition().y > 675 && snakeDirection == 3)
return true;
if (snakeBody.front().getPosition().x > 975 && snakeDirection == 4)
return true;
return false;
}
// Move snake based on direction and test for eating food
void Snake::MoveSnake(SnakeFood& snakeFood, sf::VideoMode gameVideoMode)
{
// CheckDirection();
sf::Vector2f newHeadPosition;
newHeadPosition = GetSnakeHeadPosition();
if (CheckBoundaries())
return;
newHeadPosition = CalculateNewPosition(snakeDirection, newHeadPosition);
sf::RectangleShape newBodyPart(sf::Vector2f(25,25));
newBodyPart.setPosition(newHeadPosition);
if (IsSelfCollision(newBodyPart)) // Do nothing if self collision
{
return;
}
newBodyPart.setFillColor(sf::Color::Green);
snakeBody.push_front(newBodyPart);
if (!GlobalCollision(GetSnakeHead().getPosition(), snakeFood.snakeFoodObject.getPosition()))
snakeBody.pop_back();
SnakeFoodCollision(snakeFood, gameVideoMode);
return;
}
// Return the Vector2f head of snake
sf::Vector2f Snake::GetSnakeHeadPosition()
{
sf::Vector2f position;
position = snakeBody.front().getPosition();
return position;
}
// Return the RectangleShape head of snake
sf::RectangleShape Snake::GetSnakeHead()
{
sf::RectangleShape head;
head = snakeBody.front();
return head;
}
// Iterate through snake deque and draw to window
void Snake::DisplaySnake(sf::RenderWindow& window)
{
for (auto it = snakeBody.cbegin(); it != snakeBody.cend(); ++it)
{
window.draw(*it);
}
return;
}
// Test for snake self collision
bool Snake::IsSelfCollision(sf::RectangleShape testRectangle)
{
for (auto it = snakeBody.cbegin(); it != snakeBody.cend(); ++it)
{
if (GlobalCollision(testRectangle.getPosition(), (*it).getPosition()))
{
return true;
}
}
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()
{
sf::RectangleShape newBodyPart(sf::Vector2f(25,25));
newBodyPart.setFillColor(sf::Color::Green);
snakeBody.push_back(newBodyPart);
return;
}
// Constructor for snake with position
Snake::Snake(sf::Vector2f head)
{
sf::RectangleShape newBodyPart(head);
newBodyPart.setFillColor(sf::Color::Green);
snakeBody.push_back(newBodyPart);
return;
}