Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualfrazchaudhry

Posted 23 April 2013 - 12:17 AM

Hello Gamedev.net,

                               I recently finished making a breakout clone with C++ and sfml and would love to get some feedback on my rather long code. For my future projects I would like to possibly write better quality code than what I have here so would appreciate it if any of the pros would take the time to review it. I'd like to know the areas where I can improve and also anything that I am doing totally the wrong way.

                               I would also like some feedback on the game play, you can download the executable from here https://www.dropbox.com/s/t0vkmw6qk13r552/Eent%20Tord%20setup.rar

 

Here is the code:

 

Eent Tord.cpp

// Eent Tord.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


int main(int argc, _TCHAR* argv[])
{
	srand((unsigned int)time(0));	// Seed the random number generator

	Game game;	// Initialize the game object and create a window

	game.run();

	return 0;
}

stdafx.h

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>



// TODO: reference additional headers your program requires here
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

#include <memory>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <vector>
#include <fstream>
#include <sstream>

#include "Random.h"
#include "Game_Object.h"
#include "Paddle.h"
#include "Brick.h"
#include "Ball.h"
#include "Image_Manager.h"
#include "Input_Manager.h"
#include "Level_Manager.h"
#include "Game.h"

#define SCREENWIDTH 832
#define SCREENHEIGHT 600
#define	PADDLEYPOS 550.0f
#define MAXPADDLESPEED 400.0f

 

Game.h

#pragma once

class Game
{
public:
	Game(void);
	~Game(void);

	void run();
	void setTextures();
	void update();
	void drawAll();
	bool isExiting();
	void loseLife();
	int  livesLeft();
	bool isLevelWon();

	enum GAMESTATE	 { uninitialized, title, about, running, paused, gamelost, gamewon, exiting };
	sf::RenderWindow m_Window;
	sf::Event		 m_Event;

	std::vector<std::unique_ptr<Brick>>		m_Bricks;

private:
	sf::VideoMode							m_VMode;
	GAMESTATE								m_GameState;
	Image_Manager							m_imgMgr;
	Input_Manager							m_inpMgr;
	Level_Manager							m_lvlMgr;
	sf::Clock								m_Clock;
	Paddle									m_Paddle;
	Ball									m_Ball;
	sf::Sprite								m_Background;
	sf::Sprite								m_Quit;
	sf::Sprite								m_About;
	sf::Sprite								m_NewGame;
	sf::Sprite								m_GameOver;
	sf::Sprite								m_GameWon;
	sf::Sprite								m_Paused;
	sf::Text								m_AboutText;
	sf::Text								m_LivesText;
	sf::Font								m_Font;
};

 

Game.cpp

#include "stdafx.h"


Game::Game(void)
{
	// Initialize the game object.
	m_VMode.width		 = SCREENWIDTH;
	m_VMode.height		 = SCREENHEIGHT;
	m_VMode.bitsPerPixel = 32;

	m_Window.create(m_VMode, "Eent Tord (Breakout/Arkanoid clone)", sf::Style::Titlebar);	// Actually creates the window.
	m_GameState = uninitialized;
	m_Font.loadFromFile("C:/Windows/Fonts/arial.ttf");
	m_AboutText.setFont(m_Font);
	m_AboutText.setCharacterSize(16);
	m_LivesText.setFont(m_Font);
	m_LivesText.setCharacterSize(16);
	m_imgMgr.loadAssets();		// Loads all the image files into memory.
	m_Paddle.resetLives();
	
}

Game::~Game(void)
{
}

void Game::setTextures()
{
	static GAMESTATE background = uninitialized;
	switch (m_GameState)
	{
	case title:
		if (background != title)
		{
			m_Background.setTexture(m_imgMgr.getTitle());
			m_Quit.setTexture(m_imgMgr.getQuit());
			m_About.setTexture(m_imgMgr.getAbout());
			m_NewGame.setTexture(m_imgMgr.getNewGame());
			m_GameOver.setTexture(m_imgMgr.getLost());
			m_GameWon.setTexture(m_imgMgr.getWon());
			m_Paused.setTexture(m_imgMgr.getPaused());
			m_Paddle.getSprite().setTexture(m_imgMgr.getPaddle());
			m_Ball.getSprite().setTexture(m_imgMgr.getBall());
		}
		background = title;
		break;
	case about:
		{
			background = about;
			m_AboutText.setString("Left and right keys for movement, escape to pause, and space to launch the ball! Avoid hitting the red bricks!");
		}
		break;
	case running:
		if (background != running && background != paused)
		{
			m_Paddle.initialize();
			m_Ball.initialize();
			m_Clock.restart();
			m_Paddle.resetLives();
			if (!m_Bricks.empty())
			{
				m_Bricks.clear();
				m_lvlMgr.setupLevel(m_Bricks, m_imgMgr);
			}
			else
				m_lvlMgr.setupLevel(m_Bricks, m_imgMgr);
		}
		background = running;
		break;
	default:
		break;
	}
}

void Game::update()
{
	switch (m_GameState)
	{
	case title:
		m_Quit.setPosition(675.0f, 540.0f);
		m_About.setPosition(675.0f, 500.0f);
		m_NewGame.setPosition(670.0f, 460.0f);
		break;
	case about:
		break;
	case running:
		{
		std::stringstream printLives;
		printLives << "Lives left = ";
		printLives << m_Paddle.livesLeft();
		m_LivesText.setString(printLives.str());
		m_Paddle.update(m_Clock);
		m_Ball.update(m_Clock, m_Paddle, m_Bricks);
		}
		break;
	case gamelost:
		m_GameOver.setPosition(350.0f, 250.0f);
		break;
	case gamewon:
		m_GameWon.setPosition(350.0f, 250.0f);
		break;
	case paused:
		m_Paused.setPosition(350.0f, 250.0f);
	default:
		break;
	}
}

void Game::drawAll()
{
	switch (m_GameState)
	{
	case title:
		m_Window.draw(m_Background);
		m_Window.draw(m_Quit);
		m_Window.draw(m_About);
		m_Window.draw(m_NewGame);
		break;
	case about:
		{
		m_Window.draw(m_AboutText);
		}
		break;
	case running:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		}		
		break;
	case gamelost:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		m_Window.draw(m_GameOver);
		}		
		break;
	case gamewon:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		m_Window.draw(m_GameWon);
		}		
		break;
	case paused:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		m_Window.draw(m_Paused);
		}		
		break;
	default:
		break;
	}
}

bool Game::isLevelWon()
{
	bool isWon = false;
	int aliveBricks = 0;
	for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); iter++)
	{
		if ((*iter)->getType() == "blue" && (*iter)->isAlive() == true)
		{
			aliveBricks++;
		}
	}
	if(aliveBricks > 0)
		return false;
	else
		return true;
}

void Game::run()
{
	//m_Window.setFramerateLimit(60);
	m_GameState = title;

	while (!isExiting())	// This is the main game loop responsible for handling events, updating game logic and drawing assets.
	{
		m_Window.pollEvent(m_Event);

		static Input_Manager::titleResult tresult;
		static Input_Manager::aboutResult aresult;
		static Input_Manager::gameResult  gresult;
		static Input_Manager::gamelostResult lresult;
		static Input_Manager::gamewonResult wresult;
		static Input_Manager::pauseResult presult;

		switch (m_GameState)
		{
		case title:
			tresult = m_inpMgr.titleEvents(m_Event);	// Accesses the titleEvents function in input manager class and returns a result.
			if (tresult == Input_Manager::exit)			// Based on the result the game state changes appropriately.
				m_GameState = exiting;
			else if (tresult == Input_Manager::about)
				m_GameState = about;
			else if (tresult == Input_Manager::newGame)
				m_GameState = running;
			else
				break;
			break;
		case about:
			aresult = m_inpMgr.aboutEvents(m_Event);	// Accesses the aboutEvents function in input manager class and returns a result.
			if (aresult == Input_Manager::back)			// Based on the result the game state changes appropriately.
				m_GameState = title;
			else
				break;
			break;
		case running:
			gresult = m_inpMgr.gameEvents(m_Event, m_Paddle, m_Ball);		// Accesses the gameEvents function in input manager class and returns a result.
			if (gresult == Input_Manager::prev)			// Based on the result the game state changes appropriately.
				m_GameState = title;
			else if (gresult == Input_Manager::paused)
				m_GameState = paused;
			else if (gresult == Input_Manager::idle && m_Paddle.livesLeft() > 0 && isLevelWon() == false);

			else if (gresult == Input_Manager::idle && m_Paddle.livesLeft() > 0 && isLevelWon() == true)
				m_GameState = gamewon;

			else if (gresult == Input_Manager::idle && m_Paddle.livesLeft() < 0)
				m_GameState = gamelost;
			
			else
				break;
			break;
		case gamelost:
			lresult = m_inpMgr.lostEvents(m_Event);
			if (lresult == Input_Manager::nada);

			else if (lresult == Input_Manager::mainMenu)
				m_GameState = title;
			break;
		case gamewon:
			wresult = m_inpMgr.wonEvents(m_Event);
			if (wresult == Input_Manager::idling);

			else if (wresult == Input_Manager::menu)
				m_GameState = title;
			break;
		case paused:
			presult = m_inpMgr.pauseEvents(m_Event);
			if (presult == Input_Manager::doNothing);

			else if (presult == Input_Manager::theMainMenu)
				m_GameState = title;
			else if (presult == Input_Manager::resume)
				m_GameState = running;
			break;
		default:
			break;
		}

		setTextures();		// Sets all the textures according to game states.

		update();			// Updates the position of all the items on screen

		m_Clock.restart();	// Reset the clock

		m_Window.clear();	// Clear the window to black color
		
		drawAll();			// Draws all the sprite members to the renderTarget.

		m_Window.display();	// Finally display the window.

		sf::sleep(sf::milliseconds(2));
	}

	m_Window.close();
}

bool Game::isExiting()
{
	if (m_GameState == exiting)
		return true;
	else
		return false;
}

 

Random.h

#pragma once

int Random(int a, int b);

 

Random.cpp

#include "stdafx.h"
#include "Random.h"

// Returns a random number in [low, high].
int Random(int low, int high)
{
	return low + rand() % ((high + 1) - low);
}

 

Game_Object.h

#pragma once
class Game_Object
{
public:
	Game_Object(void);
	~Game_Object(void);

	virtual void initialize();
	void setTexture(sf::Texture &texture);
	sf::Sprite& getSprite();
	sf::Vector2f getCenter();

protected:
	sf::Sprite			m_Sprite;
};

 

Game_Object.cpp

#include "StdAfx.h"
#include "Game_Object.h"


Game_Object::Game_Object(void)
{
}


Game_Object::~Game_Object(void)
{
}

void Game_Object::setTexture(sf::Texture &texture)
{
	m_Sprite.setTexture(texture);
}

sf::Sprite& Game_Object::getSprite()
{
	return m_Sprite;
}

void Game_Object::initialize()
{
}

sf::Vector2f Game_Object::getCenter()
{
	return sf::Vector2f(m_Sprite.getGlobalBounds().left + m_Sprite.getGlobalBounds().width / 2, m_Sprite.getGlobalBounds().top + m_Sprite.getGlobalBounds().height / 2);
}

 

Paddle.h

#pragma once

class Paddle : public Game_Object
{
public:
	Paddle(void);
	~Paddle(void);

	void initialize();
	void update(sf::Clock& clock);
	void resetLives();
	void loseLife();
	int livesLeft();

	float m_Speed;

private:
	int	m_Lives;
	
};

 

Paddle.cpp

#include "StdAfx.h"
#include "Paddle.h"


Paddle::Paddle(void) : m_Speed(0.0f)
{
	
}


Paddle::~Paddle(void)
{
}

void Paddle::initialize()
{
	m_Sprite.setPosition((SCREENWIDTH / 2) - (m_Sprite.getLocalBounds().width / 2), PADDLEYPOS);
	m_Speed = 0.0f;
}

void Paddle::resetLives()
{
	m_Lives = 5;
}

void Paddle::loseLife()
{
	m_Lives -= 1;
	/*if ( m_Lives < 0 )
		m_Lives = 0;*/
}

int Paddle::livesLeft()
{
	return m_Lives;
}

void Paddle::update(sf::Clock& clock)
{
	m_Sprite.move(m_Speed * clock.getElapsedTime().asSeconds(), 0.0f);

	if (m_Sprite.getPosition().x < 0.0f)			// If the sprite goes past the bounds of the window
		m_Sprite.setPosition(sf::Vector2f(0.0f, PADDLEYPOS));	// the position is reset to keep it inside the window

	else if (m_Sprite.getPosition().x + m_Sprite.getLocalBounds().width > (float)SCREENWIDTH)
		m_Sprite.setPosition(sf::Vector2f((float)SCREENWIDTH - m_Sprite.getLocalBounds().width , PADDLEYPOS));
}

 

Brick.h

#pragma once

#include "game_object.h"

class Brick : public Game_Object
{

public:
	Brick(void);
	Brick(sf::Texture& texture, std::string type);
	~Brick(void);

	void initialize();
	void setPos(sf::Vector2f pos);
	bool isAlive();
	void kill();
	std::string getType();
private:
	bool alive;
	std::string	m_Type;
};

 

Brick.cpp

#include "StdAfx.h"
#include "Brick.h"


Brick::Brick(void) : alive(true), m_Type("")
{
}

Brick::Brick(sf::Texture& texture, std::string type)
{
	m_Sprite.setTexture(texture);
	m_Type = type;
	alive = true;
}


Brick::~Brick(void)
{
}

void Brick::initialize()
{
}

std::string Brick::getType()
{
	return m_Type;
}

void Brick::setPos(sf::Vector2f pos)
{
	m_Sprite.setPosition(pos);
}

bool Brick::isAlive()
{
	if (alive)
		return true;
	else
		return false;
}

void Brick::kill()
{
	alive = false;
}

 

Ball.h

#pragma once

class Ball : public Game_Object
{
public:
	Ball(void);
	~Ball(void);

	void update(sf::Clock& clock, Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks);
	void initialize();
	void normalizeDirectionVec();
	void updatePosition(sf::Clock& clock);
	bool lineIntersects(sf::Vector2f p1, sf::Vector2f p2, sf::Vector2f p3, sf::Vector2f p4);
	void handleCollisions(Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks);

	bool			isBallMoving;
	sf::Vector2f	m_Position;
	sf::Vector2f	m_Direction;
private:
	float			m_Speed;
	sf::Vector2f	m_LastPosition;
};

 

Ball.cpp

#include "StdAfx.h"
#include "Ball.h"


Ball::Ball(void) : isBallMoving(false), m_Speed(MAXPADDLESPEED)
{
}


Ball::~Ball(void)
{
}

void Ball::initialize()
{
	if(isBallMoving)
		isBallMoving = false;

	m_Direction.x = 0.0f;
	m_Direction.y = 0.0f;

	int x = Random(-1, 1);		// Generates a random number between -1 and 1 so that the direction of the ball is randomly chosen
	m_Direction.x = static_cast<float>(x);	// between three possible directions.
	m_Direction.y = 1.0f;

	normalizeDirectionVec();

	m_Position.x = (SCREENWIDTH / 2) - (m_Sprite.getLocalBounds().width / 2);
	m_Position.y = PADDLEYPOS - 300.0f;
	m_Sprite.setPosition(m_Position);
}

void Ball::normalizeDirectionVec()
{
	float len = sqrtf(m_Direction.x * m_Direction.x + m_Direction.y * m_Direction.y); // Get the length of the vector

	m_Direction.x /= len;
	m_Direction.y /= len;
}

void Ball::update(sf::Clock& clock, Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks)
{
	if (isBallMoving)
	{
		updatePosition(clock);

		if (m_Sprite.getPosition().x + m_Sprite.getLocalBounds().width > static_cast<float>(SCREENWIDTH))
		{
			m_Sprite.setPosition(static_cast<float>(SCREENWIDTH) - m_Sprite.getLocalBounds().width, m_Sprite.getPosition().y);
			m_Direction.x = m_Direction.x * (-1);
		}
		else if (m_Sprite.getPosition().x  < 0.0f)
		{
			m_Sprite.setPosition(0.0f , m_Sprite.getPosition().y);
			m_Direction.x = m_Direction.x * (-1);
		}
		else if (m_Sprite.getPosition().y < 0.0f)
		{
			m_Sprite.setPosition(m_Sprite.getPosition().x, 0.0f);
			m_Direction.y *= (-1);
		}
		else if (m_Sprite.getPosition().y + m_Sprite.getLocalBounds().height > static_cast<float>(SCREENHEIGHT))
		{
			initialize();
			paddle.initialize();
			paddle.loseLife();
		}
		else
			handleCollisions(paddle, bricks);
	}
}

void Ball::updatePosition(sf::Clock& clock)
{
	m_Sprite.move(m_Direction.x * m_Speed * clock.getElapsedTime().asSeconds(), m_Direction.y * m_Speed * clock.getElapsedTime().asSeconds());
}

bool Ball::lineIntersects(sf::Vector2f p1, sf::Vector2f p2, sf::Vector2f p3, sf::Vector2f p4)
{
	float ua = (p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x);
	float ub = (p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x);
	float de = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);
	bool intersects = false;

	if (fabsf(de) >= 0.00001f)
	{
		ua /= de;
		ub /= de;

		if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f)
			intersects = true;
	}
	return intersects;
}

void Ball::handleCollisions(Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks)
{
	if (m_Sprite.getGlobalBounds().top > static_cast<float>(SCREENHEIGHT) / 2.0f)	// Check the position of the ball and only check for collisions with the appropriate object
	{
		if (m_Direction.y > 0.0f && paddle.getSprite().getGlobalBounds().intersects(this->getSprite().getGlobalBounds()))
		{
			m_Direction.y *= (-1);
			m_Sprite.setPosition(m_Sprite.getPosition().x, paddle.getSprite().getGlobalBounds().top - m_Sprite.getLocalBounds().height);

			m_Direction.x = (getCenter().x - paddle.getCenter().x) / (paddle.getSprite().getGlobalBounds().width / 2); // Changes the direction
			// of the ball depending upon where the ball hits the paddle.

			normalizeDirectionVec();
		}
	}
	else
	{
		sf::Vector2f centerTop(this->getSprite().getGlobalBounds().width / 2.0f, 0.0f);
		sf::Vector2f centerLeft(0.0f, this->getSprite().getGlobalBounds().height / 2.0f);
		sf::Vector2f centerRight(this->getSprite().getGlobalBounds().width, this->getSprite().getGlobalBounds().height / 2.0f);
		sf::Vector2f centerBottom(this->getSprite().getGlobalBounds().width / 2.0f, this->getSprite().getGlobalBounds().height);
		sf::Vector2f newDirection(m_Direction.x, m_Direction.y);
		bool hit = false;
		bool hitRed = false;

		for (auto iter = bricks.begin(); iter != bricks.end(); ++iter)
		{
			if (!hit)
			{
			if ((*iter)->getSprite().getGlobalBounds().intersects(this->getSprite().getGlobalBounds()))
			{
				if ((*iter)->isAlive())
				{
					bool changed = false;
					sf::Vector2f topLeft((*iter)->getSprite().getGlobalBounds().left, (*iter)->getSprite().getGlobalBounds().top);
					sf::Vector2f topRight((*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width, (*iter)->getSprite().getGlobalBounds().top);
					sf::Vector2f bottomLeft((*iter)->getSprite().getGlobalBounds().left, (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height);
					sf::Vector2f bottomRight((*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width, (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height);

					if (m_Direction.x > 0.0f && lineIntersects(m_LastPosition + centerRight, this->getSprite().getPosition() + centerRight, topLeft, bottomLeft))
					{
						newDirection.x *= -1.0f;
						std::cout << "left" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}
					else if (m_Direction.x < 0.0f && lineIntersects(m_LastPosition + centerLeft, this->getSprite().getPosition() + centerLeft, topRight, bottomRight))
					{
						newDirection.x *= -1.0f;
						std::cout << "right" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}

					if (m_Direction.y > 0.0f && lineIntersects(m_LastPosition + centerBottom, this->getSprite().getPosition() + centerBottom, topLeft, topRight))
					{
						newDirection.y *= -1.0f;
						std::cout << "top" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}
					else if (m_Direction.y < 0.0f && lineIntersects(m_LastPosition + centerTop, this->getSprite().getPosition() + centerTop, bottomLeft, bottomRight))
					{
						newDirection.y *= -1.0f;
						std::cout << "bottom" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}

					// Hit a corner
					if (!changed)
					{
						if (m_Direction.x > 0.0f && m_Direction.y < 0.0f)
						{
							if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
						else if (m_Direction.x < 0.0f && m_Direction.y < 0.0f)
						{
							if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									hitRed = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
						else if (m_Direction.x > 0.0f && m_Direction.y > 0.0f)
						{
							if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
						else
						{
							if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
					}
				}
			}
			}
			
		}
		if(!hitRed)
			m_Direction = newDirection;
		m_LastPosition = this->getSprite().getPosition();
	}

}

 

Image_Manager.h

#pragma once



class Image_Manager
{
public:
	Image_Manager(void);
	~Image_Manager(void);

	void loadAssets();

	sf::Texture& getTitle();
	sf::Texture& getQuit();
	sf::Texture& getAbout();
	sf::Texture& getNewGame();
	sf::Texture& getPaddle();
	sf::Texture& getBall();
	sf::Texture& getBlue();
	sf::Texture& getRed();
	sf::Texture& getLost();
	sf::Texture& getWon();
	sf::Texture& getPaused();

private:
	sf::Texture		m_Title;
	sf::Image		m_Image_Quit;
	sf::Texture		m_Texture_Quit;
	sf::Image		m_Image_About;
	sf::Texture		m_Texture_About;
	sf::Image		m_Image_NewGame;
	sf::Texture		m_Texture_NewGame;
	sf::Texture		m_GameLost;
	sf::Texture		m_GameWon;
	sf::Texture		m_PauseMenu;
	sf::Texture		m_Texture_Paddle;
	sf::Image		m_Image_Ball;
	sf::Texture		m_Texture_Ball;
	sf::Texture		m_Texture_Blue;
	sf::Texture		m_Texture_Red;
};

 

Image_Manager.cpp

#include "stdafx.h"


Image_Manager::Image_Manager(void)
{
}


Image_Manager::~Image_Manager(void)
{
}

void Image_Manager::loadAssets()
{
	m_Title.loadFromFile("images/title_background.png");

	m_Image_Quit.loadFromFile("images/quit.png");
	m_Image_Quit.createMaskFromColor(sf::Color::White);
	m_Texture_Quit.loadFromImage(m_Image_Quit);

	m_Image_About.loadFromFile("images/About.png");
	m_Image_About.createMaskFromColor(sf::Color::White);
	m_Texture_About.loadFromImage(m_Image_About);

	m_Image_NewGame.loadFromFile("images/new_game.png");
	m_Image_NewGame.createMaskFromColor(sf::Color::White);
	m_Texture_NewGame.loadFromImage(m_Image_NewGame);

	m_GameLost.loadFromFile("images/game_over.png");
	m_GameWon.loadFromFile("images/you_win.png");
	m_PauseMenu.loadFromFile("images/pause_menu.png");

	m_Texture_Paddle.loadFromFile("images/paddle.png");

	m_Image_Ball.loadFromFile("images/ball.png");
	m_Image_Ball.createMaskFromColor(sf::Color::White);
	m_Texture_Ball.loadFromImage(m_Image_Ball);

	m_Texture_Blue.loadFromFile("images/blue.png");
	m_Texture_Red.loadFromFile("images/red.png");
}

sf::Texture& Image_Manager::getTitle()
{
	return m_Title;
}

sf::Texture& Image_Manager::getQuit()
{
	return m_Texture_Quit;
}

sf::Texture& Image_Manager::getAbout()
{
	return m_Texture_About;
}

sf::Texture& Image_Manager::getNewGame()
{
	return m_Texture_NewGame;
}

sf::Texture& Image_Manager::getLost()
{
	return m_GameLost;
}

sf::Texture& Image_Manager::getWon()
{
	return m_GameWon;
}

sf::Texture& Image_Manager::getPaused()
{
	return this->m_PauseMenu;
}

sf::Texture& Image_Manager::getPaddle()
{
	return m_Texture_Paddle;
}

sf::Texture& Image_Manager::getBall()
{
	return m_Texture_Ball;
}

sf::Texture& Image_Manager::getBlue()
{
	return m_Texture_Blue;
}

sf::Texture& Image_Manager::getRed()
{
	return m_Texture_Red;
}

 

Input_Manager.h

#pragma once

class Input_Manager
{
public:
	Input_Manager(void);
	~Input_Manager(void);

	enum titleResult { newGame, about, exit, nothing };
	enum aboutResult { noAction, back };
	enum gameResult { idle, prev, paused };
	enum gamelostResult { mainMenu, nada };
	enum gamewonResult { menu, idling };
	enum pauseResult { theMainMenu, resume, doNothing };

	titleResult titleEvents(sf::Event &Event);
	aboutResult aboutEvents(sf::Event &Event);
	gamelostResult lostEvents(sf::Event &Event);
	gamewonResult wonEvents(sf::Event &Event);
	pauseResult pauseEvents(sf::Event &Event);
	gameResult gameEvents(sf::Event &Event, Paddle& paddle, Ball& ball);
};

 

Input_Manager.cpp

#include "StdAfx.h"


Input_Manager::Input_Manager(void)
{
}


Input_Manager::~Input_Manager(void)
{
}

Input_Manager::titleResult Input_Manager::titleEvents(sf::Event &Event)
{
	switch(Event.type)
		{
		case sf::Event::Closed:
			return exit;
			break;
		case sf::Event::KeyPressed:
			switch(Event.key.code)
			{
			case sf::Keyboard::Escape:
				return exit;
				break;
			default:
				return nothing;
				break;
			}
		case sf::Event::MouseButtonPressed:
			if (Event.mouseButton.button == sf::Mouse::Left)		// If mouse click is inside the Quit button
			{														// The application will exit.
				if(Event.mouseButton.x > 675.0f
					&& Event.mouseButton.x < 675.0f + 54.0f
					&& Event.mouseButton.y > 540.0f
					&& Event.mouseButton.y < 540.0f + 16.0f)
					return exit;
				else if (Event.mouseButton.x > 675.0f
					&& Event.mouseButton.x < 675.0f + 64.0f			// If mouse click is inside the about button
					&& Event.mouseButton.y > 500.0f					// The application will display the about screen.
					&& Event.mouseButton.y < 500.0f + 22.0f)
					return about;
				else if (Event.mouseButton.x > 670.0f				// If mouse click is inside the new game button
					&& Event.mouseButton.x < 675.0f + 108.0f		// The application will display the game screen.
					&& Event.mouseButton.y > 460.0f
					&& Event.mouseButton.y < 460.0f + 32.0f)
					return newGame;
				else
					return nothing;
			}
			else
				return nothing;
			break;
		default:
			return nothing;
			break;
		}
	return nothing;
}

Input_Manager::aboutResult Input_Manager::aboutEvents(sf::Event& Event)
{
	switch(Event.type)
		{
		case sf::Event::Closed:
			return back;
			break;
		case sf::Event::KeyPressed:
			switch(Event.key.code)
			{
			case sf::Keyboard::Escape:
				return back;
				break;
			default:
				return noAction;
				break;
			}
		case sf::Event::MouseButtonPressed:
			if (Event.mouseButton.button == sf::Mouse::Left)
			{
				if(Event.mouseButton.x > 0.0f						// Clicking the mouse button anywhere inside the
					&& Event.mouseButton.x < (float)SCREENWIDTH					// window will take it back to the title screen.
					&& Event.mouseButton.y > 0.0f
					&& Event.mouseButton.y < (float)SCREENHEIGHT)
					return back;
				else
					return noAction;
			}
		default:
			return noAction;
			break;
		}
	return noAction;
}

Input_Manager::gameResult Input_Manager::gameEvents(sf::Event& Event, Paddle& paddle, Ball& ball)
{
	switch(Event.type)
		{
		case sf::Event::Closed:
			return prev;
			break;
		case sf::Event::KeyPressed:
			switch(Event.key.code)
			{
			case sf::Keyboard::Escape:
				return paused;
				break;
			case sf::Keyboard::Left:
				if (ball.isBallMoving)
				{
					paddle.m_Speed -= 40.0f;
					if (paddle.m_Speed < -MAXPADDLESPEED)
						paddle.m_Speed = -MAXPADDLESPEED;
				}
				return idle;
				break;
			case sf::Keyboard::Right:
				if (ball.isBallMoving)
				{
					paddle.m_Speed += 40.0f;
				    if (paddle.m_Speed > MAXPADDLESPEED)
						paddle.m_Speed = MAXPADDLESPEED;
				}
				return idle;
				break;
			case sf::Keyboard::Space:
				if(!ball.isBallMoving)
					ball.isBallMoving = true;
				return idle;
				break;
			default:
				return idle;
				break;
			}
		case sf::Event::KeyReleased:
			switch(Event.key.code)
			{
			case sf::Keyboard::Left:
				paddle.m_Speed = 0.0f;
				return idle;
				break;
			case sf::Keyboard::Right:
				paddle.m_Speed = 0.0f;
				return idle;
				break;
			default:
				return idle;
				break;
			}
		default:
			return idle;
			break;
		}
	return idle;
}

Input_Manager::gamelostResult Input_Manager::lostEvents(sf::Event &Event)
{
	switch (Event.type)
	{
	case sf::Event::MouseButtonPressed:
		if (Event.mouseButton.button == sf::Mouse::Left)
		{
			if (Event.mouseButton.x	>= 380.0f &&
				Event.mouseButton.x <= 460.0f &&
				Event.mouseButton.y	>= 385.0f &&
				Event.mouseButton.y	<= 400.0f)
				return mainMenu;
		}
		break;
	default:
		break;
	}
	return nada;
}

Input_Manager::gamewonResult Input_Manager::wonEvents(sf::Event &Event)
{
	switch (Event.type)
	{
	case sf::Event::MouseButtonPressed:
		if (Event.mouseButton.button == sf::Mouse::Left)
		{
			if (Event.mouseButton.x	>= 380.0f &&
				Event.mouseButton.x <= 460.0f &&
				Event.mouseButton.y	>= 375.0f &&
				Event.mouseButton.y	<= 385.0f)
				return menu;
		}
		break;
	default:
		break;
	}
	return idling;
}

Input_Manager::pauseResult Input_Manager::pauseEvents(sf::Event &Event)
{
	switch (Event.type)
	{
	case sf::Event::MouseButtonPressed:
		if (Event.mouseButton.button == sf::Mouse::Left)
		{
			if (Event.mouseButton.x	>= 385.0f &&
				Event.mouseButton.x <= 445.0f &&
				Event.mouseButton.y	>= 260.0f &&
				Event.mouseButton.y	<= 280.0f)
				return resume;
			else if (Event.mouseButton.x >= 370.0f &&
					 Event.mouseButton.x <= 440.0f &&
					 Event.mouseButton.y >= 375.0f &&
					 Event.mouseButton.y <= 390.0f)
					 return theMainMenu;
		}
		break;
	case sf::Event::KeyPressed:
		switch (Event.key.code)
		{
		case sf::Keyboard::Escape:
			return resume;
		}
	default:
		break;
	}
	return doNothing;
}

 

Level_Manager.h

#pragma once

class Level_Manager
{
public:
	Level_Manager(void);
	~Level_Manager(void);

	void setLevel(int level);
	void setupLevel(std::vector<std::unique_ptr<Brick>>& bricks, Image_Manager& m_imgMgr);
	int getCurrentLevel();
	int getNumberOfLevels();
	void addBrick(int num);

private:
	int				m_Current_Level;
	std::vector<int>	m_brickType;
};

 

Level_Manger.cpp

#include "StdAfx.h"
#include "Level_Manager.h"


Level_Manager::Level_Manager(void) : m_Current_Level(1)
{
	
}


Level_Manager::~Level_Manager(void)
{
}

void Level_Manager::setLevel(int level)
{
	m_Current_Level = level;
}

void Level_Manager::setupLevel(std::vector<std::unique_ptr<Brick>>& bricks, Image_Manager& m_imgMgr)
{
	m_brickType.clear();
	const int MAXBRICKS = 65;
	float xPos = 0.0f, yPos = 50.0f;
	const float HOFFSET = 64.0f;
	const float VOFFSET = 20.0f;
	const int BRICKROW = 13;
	int count = 0;
	std::ifstream inFile("levels/Walls.txt");
	if (inFile)
	{
		int numLevel = 0, level = 0, type = 0;
		std::string garbage = "";
		inFile >> garbage >> numLevel;
		inFile >> garbage >> level;
		for ( int i = 0; i < MAXBRICKS; ++i )
		{
			inFile >> type;
			m_brickType.push_back(type);
		}

		for (auto iter = m_brickType.begin(); iter != m_brickType.end(); ++iter)
			{
				std::string type = "";
				if ( *iter == 1 )
				{
					type = "blue";
					bricks.push_back(std::unique_ptr<Brick>(new Brick(m_imgMgr.getBlue(), type)));
					
				}
				else if ( *iter == 2)
				{
					type = "red";
					bricks.push_back(std::unique_ptr<Brick>(new Brick(m_imgMgr.getRed(), type)));
				}
				}

				for (auto iter = bricks.begin(); iter != bricks.end(); iter++)
				{
					(*iter)->setPos(sf::Vector2f(xPos, yPos));
					xPos += HOFFSET;
					count++;
					if ( count % BRICKROW == 0 )
					{
						xPos = 0.0f;
						yPos += VOFFSET;
					}
				}
		
	}
	else
		std::cout << "Could not open file!" << std::endl;
}

int Level_Manager::getCurrentLevel()
{
	return m_Current_Level;
}

int Level_Manager::getNumberOfLevels()
{
	return 1;						// To be updated later!!!!
}

void Level_Manager::addBrick(int num)
{
	m_brickType.push_back(num);
}


#1frazchaudhry

Posted 21 April 2013 - 03:54 AM

Hello Gamedev.net,

                               I recently finished making a breakout clone with C++ and sfml and would love to get some feedback on my rather long code. For my future projects I would like to possibly write better quality code than what I have here so would appreciate it if any of the pros would take the time to review it. I'd like to know the areas where I can improve and also anything that I am doing totally the wrong way.

                               I would also like some feedback on the game play, you can download the executable from here https://www.dropbox.com/s/sbwa5dpes4xyph7/Eent%20Tord%20setup.exe .

 

Here is the code:

 

Eent Tord.cpp

// Eent Tord.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


int main(int argc, _TCHAR* argv[])
{
	srand((unsigned int)time(0));	// Seed the random number generator

	Game game;	// Initialize the game object and create a window

	game.run();

	return 0;
}

stdafx.h

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>



// TODO: reference additional headers your program requires here
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

#include <memory>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <vector>
#include <fstream>
#include <sstream>

#include "Random.h"
#include "Game_Object.h"
#include "Paddle.h"
#include "Brick.h"
#include "Ball.h"
#include "Image_Manager.h"
#include "Input_Manager.h"
#include "Level_Manager.h"
#include "Game.h"

#define SCREENWIDTH 832
#define SCREENHEIGHT 600
#define	PADDLEYPOS 550.0f
#define MAXPADDLESPEED 400.0f

 

Game.h

#pragma once

class Game
{
public:
	Game(void);
	~Game(void);

	void run();
	void setTextures();
	void update();
	void drawAll();
	bool isExiting();
	void loseLife();
	int  livesLeft();
	bool isLevelWon();

	enum GAMESTATE	 { uninitialized, title, about, running, paused, gamelost, gamewon, exiting };
	sf::RenderWindow m_Window;
	sf::Event		 m_Event;

	std::vector<std::unique_ptr<Brick>>		m_Bricks;

private:
	sf::VideoMode							m_VMode;
	GAMESTATE								m_GameState;
	Image_Manager							m_imgMgr;
	Input_Manager							m_inpMgr;
	Level_Manager							m_lvlMgr;
	sf::Clock								m_Clock;
	Paddle									m_Paddle;
	Ball									m_Ball;
	sf::Sprite								m_Background;
	sf::Sprite								m_Quit;
	sf::Sprite								m_About;
	sf::Sprite								m_NewGame;
	sf::Sprite								m_GameOver;
	sf::Sprite								m_GameWon;
	sf::Sprite								m_Paused;
	sf::Text								m_AboutText;
	sf::Text								m_LivesText;
	sf::Font								m_Font;
};

 

Game.cpp

#include "stdafx.h"


Game::Game(void)
{
	// Initialize the game object.
	m_VMode.width		 = SCREENWIDTH;
	m_VMode.height		 = SCREENHEIGHT;
	m_VMode.bitsPerPixel = 32;

	m_Window.create(m_VMode, "Eent Tord (Breakout/Arkanoid clone)", sf::Style::Titlebar);	// Actually creates the window.
	m_GameState = uninitialized;
	m_Font.loadFromFile("C:/Windows/Fonts/arial.ttf");
	m_AboutText.setFont(m_Font);
	m_AboutText.setCharacterSize(16);
	m_LivesText.setFont(m_Font);
	m_LivesText.setCharacterSize(16);
	m_imgMgr.loadAssets();		// Loads all the image files into memory.
	m_Paddle.resetLives();
	
}

Game::~Game(void)
{
}

void Game::setTextures()
{
	static GAMESTATE background = uninitialized;
	switch (m_GameState)
	{
	case title:
		if (background != title)
		{
			m_Background.setTexture(m_imgMgr.getTitle());
			m_Quit.setTexture(m_imgMgr.getQuit());
			m_About.setTexture(m_imgMgr.getAbout());
			m_NewGame.setTexture(m_imgMgr.getNewGame());
			m_GameOver.setTexture(m_imgMgr.getLost());
			m_GameWon.setTexture(m_imgMgr.getWon());
			m_Paused.setTexture(m_imgMgr.getPaused());
			m_Paddle.getSprite().setTexture(m_imgMgr.getPaddle());
			m_Ball.getSprite().setTexture(m_imgMgr.getBall());
		}
		background = title;
		break;
	case about:
		{
			background = about;
			m_AboutText.setString("Left and right keys for movement, escape to pause, and space to launch the ball! Avoid hitting the red bricks!");
		}
		break;
	case running:
		if (background != running && background != paused)
		{
			m_Paddle.initialize();
			m_Ball.initialize();
			m_Clock.restart();
			m_Paddle.resetLives();
			if (!m_Bricks.empty())
			{
				m_Bricks.clear();
				m_lvlMgr.setupLevel(m_Bricks, m_imgMgr);
			}
			else
				m_lvlMgr.setupLevel(m_Bricks, m_imgMgr);
		}
		background = running;
		break;
	default:
		break;
	}
}

void Game::update()
{
	switch (m_GameState)
	{
	case title:
		m_Quit.setPosition(675.0f, 540.0f);
		m_About.setPosition(675.0f, 500.0f);
		m_NewGame.setPosition(670.0f, 460.0f);
		break;
	case about:
		break;
	case running:
		{
		std::stringstream printLives;
		printLives << "Lives left = ";
		printLives << m_Paddle.livesLeft();
		m_LivesText.setString(printLives.str());
		m_Paddle.update(m_Clock);
		m_Ball.update(m_Clock, m_Paddle, m_Bricks);
		}
		break;
	case gamelost:
		m_GameOver.setPosition(350.0f, 250.0f);
		break;
	case gamewon:
		m_GameWon.setPosition(350.0f, 250.0f);
		break;
	case paused:
		m_Paused.setPosition(350.0f, 250.0f);
	default:
		break;
	}
}

void Game::drawAll()
{
	switch (m_GameState)
	{
	case title:
		m_Window.draw(m_Background);
		m_Window.draw(m_Quit);
		m_Window.draw(m_About);
		m_Window.draw(m_NewGame);
		break;
	case about:
		{
		m_Window.draw(m_AboutText);
		}
		break;
	case running:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		}		
		break;
	case gamelost:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		m_Window.draw(m_GameOver);
		}		
		break;
	case gamewon:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		m_Window.draw(m_GameWon);
		}		
		break;
	case paused:
		{
		m_Window.draw(m_LivesText);
		m_Window.draw(m_Paddle.getSprite());
		m_Window.draw(m_Ball.getSprite());
		for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); ++iter)
		{
			if ((*iter)->isAlive())
			{
				m_Window.draw((*iter)->getSprite());
			}
		}
		m_Window.draw(m_Paused);
		}		
		break;
	default:
		break;
	}
}

bool Game::isLevelWon()
{
	bool isWon = false;
	int aliveBricks = 0;
	for (auto iter = m_Bricks.begin(); iter != m_Bricks.end(); iter++)
	{
		if ((*iter)->getType() == "blue" && (*iter)->isAlive() == true)
		{
			aliveBricks++;
		}
	}
	if(aliveBricks > 0)
		return false;
	else
		return true;
}

void Game::run()
{
	//m_Window.setFramerateLimit(60);
	m_GameState = title;

	while (!isExiting())	// This is the main game loop responsible for handling events, updating game logic and drawing assets.
	{
		m_Window.pollEvent(m_Event);

		static Input_Manager::titleResult tresult;
		static Input_Manager::aboutResult aresult;
		static Input_Manager::gameResult  gresult;
		static Input_Manager::gamelostResult lresult;
		static Input_Manager::gamewonResult wresult;
		static Input_Manager::pauseResult presult;

		switch (m_GameState)
		{
		case title:
			tresult = m_inpMgr.titleEvents(m_Event);	// Accesses the titleEvents function in input manager class and returns a result.
			if (tresult == Input_Manager::exit)			// Based on the result the game state changes appropriately.
				m_GameState = exiting;
			else if (tresult == Input_Manager::about)
				m_GameState = about;
			else if (tresult == Input_Manager::newGame)
				m_GameState = running;
			else
				break;
			break;
		case about:
			aresult = m_inpMgr.aboutEvents(m_Event);	// Accesses the aboutEvents function in input manager class and returns a result.
			if (aresult == Input_Manager::back)			// Based on the result the game state changes appropriately.
				m_GameState = title;
			else
				break;
			break;
		case running:
			gresult = m_inpMgr.gameEvents(m_Event, m_Paddle, m_Ball);		// Accesses the gameEvents function in input manager class and returns a result.
			if (gresult == Input_Manager::prev)			// Based on the result the game state changes appropriately.
				m_GameState = title;
			else if (gresult == Input_Manager::paused)
				m_GameState = paused;
			else if (gresult == Input_Manager::idle && m_Paddle.livesLeft() > 0 && isLevelWon() == false);

			else if (gresult == Input_Manager::idle && m_Paddle.livesLeft() > 0 && isLevelWon() == true)
				m_GameState = gamewon;

			else if (gresult == Input_Manager::idle && m_Paddle.livesLeft() < 0)
				m_GameState = gamelost;
			
			else
				break;
			break;
		case gamelost:
			lresult = m_inpMgr.lostEvents(m_Event);
			if (lresult == Input_Manager::nada);

			else if (lresult == Input_Manager::mainMenu)
				m_GameState = title;
			break;
		case gamewon:
			wresult = m_inpMgr.wonEvents(m_Event);
			if (wresult == Input_Manager::idling);

			else if (wresult == Input_Manager::menu)
				m_GameState = title;
			break;
		case paused:
			presult = m_inpMgr.pauseEvents(m_Event);
			if (presult == Input_Manager::doNothing);

			else if (presult == Input_Manager::theMainMenu)
				m_GameState = title;
			else if (presult == Input_Manager::resume)
				m_GameState = running;
			break;
		default:
			break;
		}

		setTextures();		// Sets all the textures according to game states.

		update();			// Updates the position of all the items on screen

		m_Clock.restart();	// Reset the clock

		m_Window.clear();	// Clear the window to black color
		
		drawAll();			// Draws all the sprite members to the renderTarget.

		m_Window.display();	// Finally display the window.

		sf::sleep(sf::milliseconds(2));
	}

	m_Window.close();
}

bool Game::isExiting()
{
	if (m_GameState == exiting)
		return true;
	else
		return false;
}

 

Random.h

#pragma once

int Random(int a, int b);

 

Random.cpp

#include "stdafx.h"
#include "Random.h"

// Returns a random number in [low, high].
int Random(int low, int high)
{
	return low + rand() % ((high + 1) - low);
}

 

Game_Object.h

#pragma once
class Game_Object
{
public:
	Game_Object(void);
	~Game_Object(void);

	virtual void initialize();
	void setTexture(sf::Texture &texture);
	sf::Sprite& getSprite();
	sf::Vector2f getCenter();

protected:
	sf::Sprite			m_Sprite;
};

 

Game_Object.cpp

#include "StdAfx.h"
#include "Game_Object.h"


Game_Object::Game_Object(void)
{
}


Game_Object::~Game_Object(void)
{
}

void Game_Object::setTexture(sf::Texture &texture)
{
	m_Sprite.setTexture(texture);
}

sf::Sprite& Game_Object::getSprite()
{
	return m_Sprite;
}

void Game_Object::initialize()
{
}

sf::Vector2f Game_Object::getCenter()
{
	return sf::Vector2f(m_Sprite.getGlobalBounds().left + m_Sprite.getGlobalBounds().width / 2, m_Sprite.getGlobalBounds().top + m_Sprite.getGlobalBounds().height / 2);
}

 

Paddle.h

#pragma once

class Paddle : public Game_Object
{
public:
	Paddle(void);
	~Paddle(void);

	void initialize();
	void update(sf::Clock& clock);
	void resetLives();
	void loseLife();
	int livesLeft();

	float m_Speed;

private:
	int	m_Lives;
	
};

 

Paddle.cpp

#include "StdAfx.h"
#include "Paddle.h"


Paddle::Paddle(void) : m_Speed(0.0f)
{
	
}


Paddle::~Paddle(void)
{
}

void Paddle::initialize()
{
	m_Sprite.setPosition((SCREENWIDTH / 2) - (m_Sprite.getLocalBounds().width / 2), PADDLEYPOS);
	m_Speed = 0.0f;
}

void Paddle::resetLives()
{
	m_Lives = 5;
}

void Paddle::loseLife()
{
	m_Lives -= 1;
	/*if ( m_Lives < 0 )
		m_Lives = 0;*/
}

int Paddle::livesLeft()
{
	return m_Lives;
}

void Paddle::update(sf::Clock& clock)
{
	m_Sprite.move(m_Speed * clock.getElapsedTime().asSeconds(), 0.0f);

	if (m_Sprite.getPosition().x < 0.0f)			// If the sprite goes past the bounds of the window
		m_Sprite.setPosition(sf::Vector2f(0.0f, PADDLEYPOS));	// the position is reset to keep it inside the window

	else if (m_Sprite.getPosition().x + m_Sprite.getLocalBounds().width > (float)SCREENWIDTH)
		m_Sprite.setPosition(sf::Vector2f((float)SCREENWIDTH - m_Sprite.getLocalBounds().width , PADDLEYPOS));
}

 

Brick.h

#pragma once

#include "game_object.h"

class Brick : public Game_Object
{

public:
	Brick(void);
	Brick(sf::Texture& texture, std::string type);
	~Brick(void);

	void initialize();
	void setPos(sf::Vector2f pos);
	bool isAlive();
	void kill();
	std::string getType();
private:
	bool alive;
	std::string	m_Type;
};

 

Brick.cpp

#include "StdAfx.h"
#include "Brick.h"


Brick::Brick(void) : alive(true), m_Type("")
{
}

Brick::Brick(sf::Texture& texture, std::string type)
{
	m_Sprite.setTexture(texture);
	m_Type = type;
	alive = true;
}


Brick::~Brick(void)
{
}

void Brick::initialize()
{
}

std::string Brick::getType()
{
	return m_Type;
}

void Brick::setPos(sf::Vector2f pos)
{
	m_Sprite.setPosition(pos);
}

bool Brick::isAlive()
{
	if (alive)
		return true;
	else
		return false;
}

void Brick::kill()
{
	alive = false;
}

 

Ball.h

#pragma once

class Ball : public Game_Object
{
public:
	Ball(void);
	~Ball(void);

	void update(sf::Clock& clock, Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks);
	void initialize();
	void normalizeDirectionVec();
	void updatePosition(sf::Clock& clock);
	bool lineIntersects(sf::Vector2f p1, sf::Vector2f p2, sf::Vector2f p3, sf::Vector2f p4);
	void handleCollisions(Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks);

	bool			isBallMoving;
	sf::Vector2f	m_Position;
	sf::Vector2f	m_Direction;
private:
	float			m_Speed;
	sf::Vector2f	m_LastPosition;
};

 

Ball.cpp

#include "StdAfx.h"
#include "Ball.h"


Ball::Ball(void) : isBallMoving(false), m_Speed(MAXPADDLESPEED)
{
}


Ball::~Ball(void)
{
}

void Ball::initialize()
{
	if(isBallMoving)
		isBallMoving = false;

	m_Direction.x = 0.0f;
	m_Direction.y = 0.0f;

	int x = Random(-1, 1);		// Generates a random number between -1 and 1 so that the direction of the ball is randomly chosen
	m_Direction.x = static_cast<float>(x);	// between three possible directions.
	m_Direction.y = 1.0f;

	normalizeDirectionVec();

	m_Position.x = (SCREENWIDTH / 2) - (m_Sprite.getLocalBounds().width / 2);
	m_Position.y = PADDLEYPOS - 300.0f;
	m_Sprite.setPosition(m_Position);
}

void Ball::normalizeDirectionVec()
{
	float len = sqrtf(m_Direction.x * m_Direction.x + m_Direction.y * m_Direction.y); // Get the length of the vector

	m_Direction.x /= len;
	m_Direction.y /= len;
}

void Ball::update(sf::Clock& clock, Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks)
{
	if (isBallMoving)
	{
		updatePosition(clock);

		if (m_Sprite.getPosition().x + m_Sprite.getLocalBounds().width > static_cast<float>(SCREENWIDTH))
		{
			m_Sprite.setPosition(static_cast<float>(SCREENWIDTH) - m_Sprite.getLocalBounds().width, m_Sprite.getPosition().y);
			m_Direction.x = m_Direction.x * (-1);
		}
		else if (m_Sprite.getPosition().x  < 0.0f)
		{
			m_Sprite.setPosition(0.0f , m_Sprite.getPosition().y);
			m_Direction.x = m_Direction.x * (-1);
		}
		else if (m_Sprite.getPosition().y < 0.0f)
		{
			m_Sprite.setPosition(m_Sprite.getPosition().x, 0.0f);
			m_Direction.y *= (-1);
		}
		else if (m_Sprite.getPosition().y + m_Sprite.getLocalBounds().height > static_cast<float>(SCREENHEIGHT))
		{
			initialize();
			paddle.initialize();
			paddle.loseLife();
		}
		else
			handleCollisions(paddle, bricks);
	}
}

void Ball::updatePosition(sf::Clock& clock)
{
	m_Sprite.move(m_Direction.x * m_Speed * clock.getElapsedTime().asSeconds(), m_Direction.y * m_Speed * clock.getElapsedTime().asSeconds());
}

bool Ball::lineIntersects(sf::Vector2f p1, sf::Vector2f p2, sf::Vector2f p3, sf::Vector2f p4)
{
	float ua = (p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x);
	float ub = (p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x);
	float de = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);
	bool intersects = false;

	if (fabsf(de) >= 0.00001f)
	{
		ua /= de;
		ub /= de;

		if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f)
			intersects = true;
	}
	return intersects;
}

void Ball::handleCollisions(Paddle& paddle, std::vector<std::unique_ptr<Brick>>& bricks)
{
	if (m_Sprite.getGlobalBounds().top > static_cast<float>(SCREENHEIGHT) / 2.0f)	// Check the position of the ball and only check for collisions with the appropriate object
	{
		if (m_Direction.y > 0.0f && paddle.getSprite().getGlobalBounds().intersects(this->getSprite().getGlobalBounds()))
		{
			m_Direction.y *= (-1);
			m_Sprite.setPosition(m_Sprite.getPosition().x, paddle.getSprite().getGlobalBounds().top - m_Sprite.getLocalBounds().height);

			m_Direction.x = (getCenter().x - paddle.getCenter().x) / (paddle.getSprite().getGlobalBounds().width / 2); // Changes the direction
			// of the ball depending upon where the ball hits the paddle.

			normalizeDirectionVec();
		}
	}
	else
	{
		sf::Vector2f centerTop(this->getSprite().getGlobalBounds().width / 2.0f, 0.0f);
		sf::Vector2f centerLeft(0.0f, this->getSprite().getGlobalBounds().height / 2.0f);
		sf::Vector2f centerRight(this->getSprite().getGlobalBounds().width, this->getSprite().getGlobalBounds().height / 2.0f);
		sf::Vector2f centerBottom(this->getSprite().getGlobalBounds().width / 2.0f, this->getSprite().getGlobalBounds().height);
		sf::Vector2f newDirection(m_Direction.x, m_Direction.y);
		bool hit = false;
		bool hitRed = false;

		for (auto iter = bricks.begin(); iter != bricks.end(); ++iter)
		{
			if (!hit)
			{
			if ((*iter)->getSprite().getGlobalBounds().intersects(this->getSprite().getGlobalBounds()))
			{
				if ((*iter)->isAlive())
				{
					bool changed = false;
					sf::Vector2f topLeft((*iter)->getSprite().getGlobalBounds().left, (*iter)->getSprite().getGlobalBounds().top);
					sf::Vector2f topRight((*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width, (*iter)->getSprite().getGlobalBounds().top);
					sf::Vector2f bottomLeft((*iter)->getSprite().getGlobalBounds().left, (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height);
					sf::Vector2f bottomRight((*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width, (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height);

					if (m_Direction.x > 0.0f && lineIntersects(m_LastPosition + centerRight, this->getSprite().getPosition() + centerRight, topLeft, bottomLeft))
					{
						newDirection.x *= -1.0f;
						std::cout << "left" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}
					else if (m_Direction.x < 0.0f && lineIntersects(m_LastPosition + centerLeft, this->getSprite().getPosition() + centerLeft, topRight, bottomRight))
					{
						newDirection.x *= -1.0f;
						std::cout << "right" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}

					if (m_Direction.y > 0.0f && lineIntersects(m_LastPosition + centerBottom, this->getSprite().getPosition() + centerBottom, topLeft, topRight))
					{
						newDirection.y *= -1.0f;
						std::cout << "top" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}
					else if (m_Direction.y < 0.0f && lineIntersects(m_LastPosition + centerTop, this->getSprite().getPosition() + centerTop, bottomLeft, bottomRight))
					{
						newDirection.y *= -1.0f;
						std::cout << "bottom" << std::endl;
						if ((*iter)->getType() == "blue")
						{
							(*iter)->kill();
							changed = true;
							hit = true;
							break;
						}
						else if ((*iter)->getType() == "red")
						{
							initialize();
							paddle.initialize();
							paddle.loseLife();
							hitRed = true;
							break;
						}
					}

					// Hit a corner
					if (!changed)
					{
						if (m_Direction.x > 0.0f && m_Direction.y < 0.0f)
						{
							if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
						else if (m_Direction.x < 0.0f && m_Direction.y < 0.0f)
						{
							if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y > (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									hitRed = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
						else if (m_Direction.x > 0.0f && m_Direction.y > 0.0f)
						{
							if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
						else
						{
							if (this->getSprite().getPosition().x > (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.x *= -1.0f;
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else if (this->getSprite().getPosition().x < (*iter)->getSprite().getGlobalBounds().left + (*iter)->getSprite().getGlobalBounds().width / 2.0f && this->getSprite().getPosition().y < (*iter)->getSprite().getGlobalBounds().top + (*iter)->getSprite().getGlobalBounds().height / 2.0f)
							{
								newDirection.y *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
							else
							{
								newDirection.x *= -1.0f;
								if ((*iter)->getType() == "blue")
								{
									(*iter)->kill();
									changed = true;
									hit = true;
									break;
								}
								else if ((*iter)->getType() == "red")
								{
									initialize();
									paddle.initialize();
									paddle.loseLife();
									hitRed = true;
									break;
								}
								std::cout << "corner" << std::endl;
							}
						}
					}
				}
			}
			}
			
		}
		if(!hitRed)
			m_Direction = newDirection;
		m_LastPosition = this->getSprite().getPosition();
	}

}

 

Image_Manager.h

#pragma once



class Image_Manager
{
public:
	Image_Manager(void);
	~Image_Manager(void);

	void loadAssets();

	sf::Texture& getTitle();
	sf::Texture& getQuit();
	sf::Texture& getAbout();
	sf::Texture& getNewGame();
	sf::Texture& getPaddle();
	sf::Texture& getBall();
	sf::Texture& getBlue();
	sf::Texture& getRed();
	sf::Texture& getLost();
	sf::Texture& getWon();
	sf::Texture& getPaused();

private:
	sf::Texture		m_Title;
	sf::Image		m_Image_Quit;
	sf::Texture		m_Texture_Quit;
	sf::Image		m_Image_About;
	sf::Texture		m_Texture_About;
	sf::Image		m_Image_NewGame;
	sf::Texture		m_Texture_NewGame;
	sf::Texture		m_GameLost;
	sf::Texture		m_GameWon;
	sf::Texture		m_PauseMenu;
	sf::Texture		m_Texture_Paddle;
	sf::Image		m_Image_Ball;
	sf::Texture		m_Texture_Ball;
	sf::Texture		m_Texture_Blue;
	sf::Texture		m_Texture_Red;
};

 

Image_Manager.cpp

#include "stdafx.h"


Image_Manager::Image_Manager(void)
{
}


Image_Manager::~Image_Manager(void)
{
}

void Image_Manager::loadAssets()
{
	m_Title.loadFromFile("images/title_background.png");

	m_Image_Quit.loadFromFile("images/quit.png");
	m_Image_Quit.createMaskFromColor(sf::Color::White);
	m_Texture_Quit.loadFromImage(m_Image_Quit);

	m_Image_About.loadFromFile("images/About.png");
	m_Image_About.createMaskFromColor(sf::Color::White);
	m_Texture_About.loadFromImage(m_Image_About);

	m_Image_NewGame.loadFromFile("images/new_game.png");
	m_Image_NewGame.createMaskFromColor(sf::Color::White);
	m_Texture_NewGame.loadFromImage(m_Image_NewGame);

	m_GameLost.loadFromFile("images/game_over.png");
	m_GameWon.loadFromFile("images/you_win.png");
	m_PauseMenu.loadFromFile("images/pause_menu.png");

	m_Texture_Paddle.loadFromFile("images/paddle.png");

	m_Image_Ball.loadFromFile("images/ball.png");
	m_Image_Ball.createMaskFromColor(sf::Color::White);
	m_Texture_Ball.loadFromImage(m_Image_Ball);

	m_Texture_Blue.loadFromFile("images/blue.png");
	m_Texture_Red.loadFromFile("images/red.png");
}

sf::Texture& Image_Manager::getTitle()
{
	return m_Title;
}

sf::Texture& Image_Manager::getQuit()
{
	return m_Texture_Quit;
}

sf::Texture& Image_Manager::getAbout()
{
	return m_Texture_About;
}

sf::Texture& Image_Manager::getNewGame()
{
	return m_Texture_NewGame;
}

sf::Texture& Image_Manager::getLost()
{
	return m_GameLost;
}

sf::Texture& Image_Manager::getWon()
{
	return m_GameWon;
}

sf::Texture& Image_Manager::getPaused()
{
	return this->m_PauseMenu;
}

sf::Texture& Image_Manager::getPaddle()
{
	return m_Texture_Paddle;
}

sf::Texture& Image_Manager::getBall()
{
	return m_Texture_Ball;
}

sf::Texture& Image_Manager::getBlue()
{
	return m_Texture_Blue;
}

sf::Texture& Image_Manager::getRed()
{
	return m_Texture_Red;
}

 

Input_Manager.h

#pragma once

class Input_Manager
{
public:
	Input_Manager(void);
	~Input_Manager(void);

	enum titleResult { newGame, about, exit, nothing };
	enum aboutResult { noAction, back };
	enum gameResult { idle, prev, paused };
	enum gamelostResult { mainMenu, nada };
	enum gamewonResult { menu, idling };
	enum pauseResult { theMainMenu, resume, doNothing };

	titleResult titleEvents(sf::Event &Event);
	aboutResult aboutEvents(sf::Event &Event);
	gamelostResult lostEvents(sf::Event &Event);
	gamewonResult wonEvents(sf::Event &Event);
	pauseResult pauseEvents(sf::Event &Event);
	gameResult gameEvents(sf::Event &Event, Paddle& paddle, Ball& ball);
};

 

Input_Manager.cpp

#include "StdAfx.h"


Input_Manager::Input_Manager(void)
{
}


Input_Manager::~Input_Manager(void)
{
}

Input_Manager::titleResult Input_Manager::titleEvents(sf::Event &Event)
{
	switch(Event.type)
		{
		case sf::Event::Closed:
			return exit;
			break;
		case sf::Event::KeyPressed:
			switch(Event.key.code)
			{
			case sf::Keyboard::Escape:
				return exit;
				break;
			default:
				return nothing;
				break;
			}
		case sf::Event::MouseButtonPressed:
			if (Event.mouseButton.button == sf::Mouse::Left)		// If mouse click is inside the Quit button
			{														// The application will exit.
				if(Event.mouseButton.x > 675.0f
					&& Event.mouseButton.x < 675.0f + 54.0f
					&& Event.mouseButton.y > 540.0f
					&& Event.mouseButton.y < 540.0f + 16.0f)
					return exit;
				else if (Event.mouseButton.x > 675.0f
					&& Event.mouseButton.x < 675.0f + 64.0f			// If mouse click is inside the about button
					&& Event.mouseButton.y > 500.0f					// The application will display the about screen.
					&& Event.mouseButton.y < 500.0f + 22.0f)
					return about;
				else if (Event.mouseButton.x > 670.0f				// If mouse click is inside the new game button
					&& Event.mouseButton.x < 675.0f + 108.0f		// The application will display the game screen.
					&& Event.mouseButton.y > 460.0f
					&& Event.mouseButton.y < 460.0f + 32.0f)
					return newGame;
				else
					return nothing;
			}
			else
				return nothing;
			break;
		default:
			return nothing;
			break;
		}
	return nothing;
}

Input_Manager::aboutResult Input_Manager::aboutEvents(sf::Event& Event)
{
	switch(Event.type)
		{
		case sf::Event::Closed:
			return back;
			break;
		case sf::Event::KeyPressed:
			switch(Event.key.code)
			{
			case sf::Keyboard::Escape:
				return back;
				break;
			default:
				return noAction;
				break;
			}
		case sf::Event::MouseButtonPressed:
			if (Event.mouseButton.button == sf::Mouse::Left)
			{
				if(Event.mouseButton.x > 0.0f						// Clicking the mouse button anywhere inside the
					&& Event.mouseButton.x < (float)SCREENWIDTH					// window will take it back to the title screen.
					&& Event.mouseButton.y > 0.0f
					&& Event.mouseButton.y < (float)SCREENHEIGHT)
					return back;
				else
					return noAction;
			}
		default:
			return noAction;
			break;
		}
	return noAction;
}

Input_Manager::gameResult Input_Manager::gameEvents(sf::Event& Event, Paddle& paddle, Ball& ball)
{
	switch(Event.type)
		{
		case sf::Event::Closed:
			return prev;
			break;
		case sf::Event::KeyPressed:
			switch(Event.key.code)
			{
			case sf::Keyboard::Escape:
				return paused;
				break;
			case sf::Keyboard::Left:
				if (ball.isBallMoving)
				{
					paddle.m_Speed -= 40.0f;
					if (paddle.m_Speed < -MAXPADDLESPEED)
						paddle.m_Speed = -MAXPADDLESPEED;
				}
				return idle;
				break;
			case sf::Keyboard::Right:
				if (ball.isBallMoving)
				{
					paddle.m_Speed += 40.0f;
				    if (paddle.m_Speed > MAXPADDLESPEED)
						paddle.m_Speed = MAXPADDLESPEED;
				}
				return idle;
				break;
			case sf::Keyboard::Space:
				if(!ball.isBallMoving)
					ball.isBallMoving = true;
				return idle;
				break;
			default:
				return idle;
				break;
			}
		case sf::Event::KeyReleased:
			switch(Event.key.code)
			{
			case sf::Keyboard::Left:
				paddle.m_Speed = 0.0f;
				return idle;
				break;
			case sf::Keyboard::Right:
				paddle.m_Speed = 0.0f;
				return idle;
				break;
			default:
				return idle;
				break;
			}
		default:
			return idle;
			break;
		}
	return idle;
}

Input_Manager::gamelostResult Input_Manager::lostEvents(sf::Event &Event)
{
	switch (Event.type)
	{
	case sf::Event::MouseButtonPressed:
		if (Event.mouseButton.button == sf::Mouse::Left)
		{
			if (Event.mouseButton.x	>= 380.0f &&
				Event.mouseButton.x <= 460.0f &&
				Event.mouseButton.y	>= 385.0f &&
				Event.mouseButton.y	<= 400.0f)
				return mainMenu;
		}
		break;
	default:
		break;
	}
	return nada;
}

Input_Manager::gamewonResult Input_Manager::wonEvents(sf::Event &Event)
{
	switch (Event.type)
	{
	case sf::Event::MouseButtonPressed:
		if (Event.mouseButton.button == sf::Mouse::Left)
		{
			if (Event.mouseButton.x	>= 380.0f &&
				Event.mouseButton.x <= 460.0f &&
				Event.mouseButton.y	>= 375.0f &&
				Event.mouseButton.y	<= 385.0f)
				return menu;
		}
		break;
	default:
		break;
	}
	return idling;
}

Input_Manager::pauseResult Input_Manager::pauseEvents(sf::Event &Event)
{
	switch (Event.type)
	{
	case sf::Event::MouseButtonPressed:
		if (Event.mouseButton.button == sf::Mouse::Left)
		{
			if (Event.mouseButton.x	>= 385.0f &&
				Event.mouseButton.x <= 445.0f &&
				Event.mouseButton.y	>= 260.0f &&
				Event.mouseButton.y	<= 280.0f)
				return resume;
			else if (Event.mouseButton.x >= 370.0f &&
					 Event.mouseButton.x <= 440.0f &&
					 Event.mouseButton.y >= 375.0f &&
					 Event.mouseButton.y <= 390.0f)
					 return theMainMenu;
		}
		break;
	case sf::Event::KeyPressed:
		switch (Event.key.code)
		{
		case sf::Keyboard::Escape:
			return resume;
		}
	default:
		break;
	}
	return doNothing;
}

 

Level_Manager.h

#pragma once

class Level_Manager
{
public:
	Level_Manager(void);
	~Level_Manager(void);

	void setLevel(int level);
	void setupLevel(std::vector<std::unique_ptr<Brick>>& bricks, Image_Manager& m_imgMgr);
	int getCurrentLevel();
	int getNumberOfLevels();
	void addBrick(int num);

private:
	int				m_Current_Level;
	std::vector<int>	m_brickType;
};

 

Level_Manger.cpp

#include "StdAfx.h"
#include "Level_Manager.h"


Level_Manager::Level_Manager(void) : m_Current_Level(1)
{
	
}


Level_Manager::~Level_Manager(void)
{
}

void Level_Manager::setLevel(int level)
{
	m_Current_Level = level;
}

void Level_Manager::setupLevel(std::vector<std::unique_ptr<Brick>>& bricks, Image_Manager& m_imgMgr)
{
	m_brickType.clear();
	const int MAXBRICKS = 65;
	float xPos = 0.0f, yPos = 50.0f;
	const float HOFFSET = 64.0f;
	const float VOFFSET = 20.0f;
	const int BRICKROW = 13;
	int count = 0;
	std::ifstream inFile("levels/Walls.txt");
	if (inFile)
	{
		int numLevel = 0, level = 0, type = 0;
		std::string garbage = "";
		inFile >> garbage >> numLevel;
		inFile >> garbage >> level;
		for ( int i = 0; i < MAXBRICKS; ++i )
		{
			inFile >> type;
			m_brickType.push_back(type);
		}

		for (auto iter = m_brickType.begin(); iter != m_brickType.end(); ++iter)
			{
				std::string type = "";
				if ( *iter == 1 )
				{
					type = "blue";
					bricks.push_back(std::unique_ptr<Brick>(new Brick(m_imgMgr.getBlue(), type)));
					
				}
				else if ( *iter == 2)
				{
					type = "red";
					bricks.push_back(std::unique_ptr<Brick>(new Brick(m_imgMgr.getRed(), type)));
				}
				}

				for (auto iter = bricks.begin(); iter != bricks.end(); iter++)
				{
					(*iter)->setPos(sf::Vector2f(xPos, yPos));
					xPos += HOFFSET;
					count++;
					if ( count % BRICKROW == 0 )
					{
						xPos = 0.0f;
						yPos += VOFFSET;
					}
				}
		
	}
	else
		std::cout << "Could not open file!" << std::endl;
}

int Level_Manager::getCurrentLevel()
{
	return m_Current_Level;
}

int Level_Manager::getNumberOfLevels()
{
	return 1;						// To be updated later!!!!
}

void Level_Manager::addBrick(int num)
{
	m_brickType.push_back(num);
}

 

 


PARTNERS