2022-08-15 23:51:18 -05:00
|
|
|
// Snake.cpp
|
2022-07-25 15:40:45 -05:00
|
|
|
#include <iostream>
|
|
|
|
#include <SFML\Graphics.hpp>
|
|
|
|
#include "Snake.h"
|
2022-08-15 23:51:18 -05:00
|
|
|
#include "SnakeFood.h"
|
2022-07-25 15:40:45 -05:00
|
|
|
|
2022-07-25 16:06:06 -05:00
|
|
|
// Test for collision between two objects
|
2022-07-25 15:40:45 -05:00
|
|
|
bool SnakeCollision(sf::RectangleShape object1, sf::RectangleShape object2)
|
|
|
|
{
|
2022-07-25 16:06:06 -05:00
|
|
|
// Hack for getting a temporary collision
|
|
|
|
// Collision only tested for origin corrordinate
|
2022-07-25 15:40:45 -05:00
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-10 19:59:48 -05:00
|
|
|
// Check keyboard for new direction of snake
|
2022-07-26 19:47:08 -05:00
|
|
|
void Snake::CheckDirection()
|
2022-07-25 15:40:45 -05:00
|
|
|
{
|
2022-07-26 19:03:55 -05:00
|
|
|
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;
|
2022-07-26 19:47:08 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check snake head for running into boundaries
|
|
|
|
bool Snake::CheckBoundaries()
|
|
|
|
{
|
|
|
|
if (snakeBody.front().getPosition().x == 0 && snakeDirection == 1)
|
2022-07-28 14:56:54 -05:00
|
|
|
return true;
|
2022-07-26 19:47:08 -05:00
|
|
|
if (snakeBody.front().getPosition().y == 0 && snakeDirection == 2)
|
2022-07-28 14:56:54 -05:00
|
|
|
return true;
|
2022-07-26 19:47:08 -05:00
|
|
|
// TODO: Change boundaries to not be hard-coded
|
|
|
|
if (snakeBody.front().getPosition().y > 675 && snakeDirection == 3)
|
2022-07-28 14:56:54 -05:00
|
|
|
return true;
|
2022-07-26 19:47:08 -05:00
|
|
|
if (snakeBody.front().getPosition().x > 975 && snakeDirection == 4)
|
2022-07-28 14:56:54 -05:00
|
|
|
return true;
|
|
|
|
return false;
|
2022-07-26 19:03:55 -05:00
|
|
|
}
|
|
|
|
|
2022-07-27 15:07:28 -05:00
|
|
|
// Get a new coordinate position based on snake direction
|
2022-07-26 19:03:55 -05:00
|
|
|
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;
|
2022-07-25 15:40:45 -05:00
|
|
|
}
|
|
|
|
|
2022-07-27 15:15:36 -05:00
|
|
|
// Move snake based on direction and test for eating food
|
2022-08-15 23:51:18 -05:00
|
|
|
void Snake::MoveSnake(SnakeFood& snakeFood, sf::VideoMode gameVideoMode)
|
2022-07-25 15:40:45 -05:00
|
|
|
{
|
2022-08-15 23:51:18 -05:00
|
|
|
// CheckDirection();
|
2022-07-26 19:03:55 -05:00
|
|
|
sf::Vector2f newHeadPosition;
|
|
|
|
newHeadPosition = GetSnakeHeadPosition();
|
2022-08-10 20:05:28 -05:00
|
|
|
if (CheckBoundaries())
|
|
|
|
return;
|
|
|
|
newHeadPosition = CalculateNewPosition(snakeDirection, newHeadPosition);
|
2022-07-26 19:24:46 -05:00
|
|
|
sf::RectangleShape newBodyPart(sf::Vector2f(25,25));
|
|
|
|
newBodyPart.setPosition(newHeadPosition);
|
2022-08-10 19:59:48 -05:00
|
|
|
if (IsSelfCollision(newBodyPart)) // Do nothing if self collision
|
2022-07-28 14:56:54 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
newBodyPart.setFillColor(sf::Color::Green);
|
2022-07-27 15:07:28 -05:00
|
|
|
snakeBody.push_front(newBodyPart);
|
2022-08-15 23:51:18 -05:00
|
|
|
if (!SnakeCollision(GetSnakeHead(), snakeFood.snakeFoodObject))
|
2022-07-27 15:07:28 -05:00
|
|
|
snakeBody.pop_back();
|
2022-08-15 23:51:18 -05:00
|
|
|
SnakeFoodCollision(snakeFood, gameVideoMode);
|
2022-07-25 16:12:11 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-27 15:15:36 -05:00
|
|
|
// Return the Vector2f head of snake
|
2022-07-26 19:03:55 -05:00
|
|
|
sf::Vector2f Snake::GetSnakeHeadPosition()
|
2022-07-26 16:56:26 -05:00
|
|
|
{
|
|
|
|
sf::Vector2f position;
|
|
|
|
position = snakeBody.front().getPosition();
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
2022-07-27 15:15:36 -05:00
|
|
|
// Return the RectangleShape head of snake
|
2022-07-26 19:03:55 -05:00
|
|
|
sf::RectangleShape Snake::GetSnakeHead()
|
|
|
|
{
|
|
|
|
sf::RectangleShape head;
|
|
|
|
head = snakeBody.front();
|
|
|
|
return head;
|
|
|
|
}
|
|
|
|
|
2022-07-27 15:15:36 -05:00
|
|
|
// Iterate through snake deque and draw to window
|
2022-07-26 19:03:55 -05:00
|
|
|
void Snake::DisplaySnake(sf::RenderWindow& window)
|
|
|
|
{
|
|
|
|
for (auto it = snakeBody.cbegin(); it != snakeBody.cend(); ++it)
|
|
|
|
{
|
|
|
|
window.draw(*it);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-28 14:56:54 -05:00
|
|
|
// Test for snake self collision
|
|
|
|
bool Snake::IsSelfCollision(sf::RectangleShape testRectangle)
|
|
|
|
{
|
|
|
|
for (auto it = snakeBody.cbegin(); it != snakeBody.cend(); ++it)
|
|
|
|
{
|
|
|
|
if (SnakeCollision(testRectangle, *it))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-08-15 23:51:18 -05:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2022-07-27 15:15:36 -05:00
|
|
|
// General constructor for snake class
|
2022-07-25 16:12:11 -05:00
|
|
|
Snake::Snake()
|
|
|
|
{
|
2022-07-27 15:15:36 -05:00
|
|
|
sf::RectangleShape newBodyPart(sf::Vector2f(25,25));
|
|
|
|
newBodyPart.setFillColor(sf::Color::Green);
|
|
|
|
snakeBody.push_back(newBodyPart);
|
2022-07-25 15:40:45 -05:00
|
|
|
return;
|
|
|
|
}
|
2022-07-27 15:15:36 -05:00
|
|
|
|
|
|
|
// Constructor for snake with position
|
2022-07-26 16:56:26 -05:00
|
|
|
Snake::Snake(sf::Vector2f head)
|
|
|
|
{
|
|
|
|
sf::RectangleShape newBodyPart(head);
|
2022-07-26 19:24:46 -05:00
|
|
|
newBodyPart.setFillColor(sf::Color::Green);
|
2022-07-26 16:56:26 -05:00
|
|
|
snakeBody.push_back(newBodyPart);
|
|
|
|
return;
|
|
|
|
}
|