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.
153 lines
4.1 KiB
C++
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;
|
|
}
|