Merge pull request #10 from TriantaTV/Development

Fixed snake food generation
This commit is contained in:
TriantaTV 2022-08-21 02:52:46 -05:00 committed by GitHub
commit 545bc2a41b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 70 additions and 63 deletions

View File

@ -1,8 +1,7 @@
// #include <iostream>
// GameState.cpp
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#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);

View File

@ -2,7 +2,6 @@
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
class GameState
{

View File

@ -1,22 +1,35 @@
// Snake.cpp
#include <iostream>
#include <queue>
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#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()
{

View File

@ -1,11 +1,9 @@
// Snake.h
#ifndef SNAKE_H
#define SNAKE_H
#include <queue>
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);

View File

@ -1,5 +1,8 @@
#include <random>
// SnakeFood.cpp
#include <iostream>
#include <SFML\Graphics.hpp>
#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<int> distribution(0, maxLocation);
newPosition.x = distribution(generator);
newPosition.y = distribution(generator);
snakeFoodObject.setPosition(newPosition);
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;
}

View File

@ -1,6 +1,7 @@
// SnakeFood.h
#ifndef SNAKEFOOD_H
#define SNAKEFOOD_H
#include <random>
#include <SFML\Graphics.hpp>
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