Code Review: Breakout

Started by
15 comments, last by rip-off 10 years, 11 months ago

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);
}

Advertisement

One, personal appeal is that i don't like to install games from untrusted sources.

Id much rather just download a zip or smt, scan, unzip, play.

I wish you luck, when someone reviews your game!

About the code:

It is nice to read(on the eyes), and mostly its nicely structured.

A good syntax you have there, makes it so easy to skim true the code and end up where the searcher wants to be.

From first .h and .cpp file i already knew how you structure the code.

Also i would like a project file much more then a whole post of files...

There is a reason why writing code is happening in IDE instead of a regular text editor.

I feel Image_Manager has too many variables. You could use unordered_map<string, sf::Texture> then acquire textures from it. This way you'll have only single variable and won't need to hardcode 200 textures.

Your switch() for game states is massive as well, see http://lspiroengine.com/?p=351 for decent solution.

One, personal appeal is that i don't like to install games from untrusted sources.

Id much rather just download a zip or smt, scan, unzip, play.

I wish you luck, when someone reviews your game!

About the code:

It is nice to read(on the eyes), and mostly its nicely structured.

A good syntax you have there, makes it so easy to skim true the code and end up where the searcher wants to be.

From first .h and .cpp file i already knew how you structure the code.

Also i would like a project file much more then a whole post of files...

There is a reason why writing code is happening in IDE instead of a regular text editor.

Thanks for the feedback. I have now replaced the executable with a .rar file. If I post a project file then people who do not have visual c++ express will probably not be able to view the code or they'll have to go through the process of installing it, and I do not want to force people to do that. But you're right if this was a bigger game than breakout then this really is a problem. For next time I'll probably put the code up on github and link to it so people can easily see it without any hassle. I appreciate you taking the time to view the code though. Thanks

I feel Image_Manager has too many variables. You could use unordered_map<string, sf::Texture> then acquire textures from it. This way you'll have only single variable and won't need to hardcode 200 textures.

Your switch() for game states is massive as well, see http://lspiroengine.com/?p=351 for decent solution.

As I was coding the game this image manager class was really bugging me. As I thought that when I work on a bigger game which has hundreds of textures this solution won't really work. But I decided to go with it for this game as it was not that big of an issue for such a small game as breakout. I now realize that using your solution would have been a much smarter way of handling this even for this type of game.

I'll look into the solution that you have provided for game states as well. Hopefully I'll be able to put out a higher quality code for my next game. I really appreciate the time you took to look at the code. Thanks a lot smile.png .

1: Thanks for the feedback. I have now replaced the executable with a .rar file.

If I post a project file then people who do not have visual c++ express will probably not be able to view the code or they'll have to go through the process of installing it

Good response:

The response seems legit enough, so i am gonna download... ( Had massive issues starting download :( )

Also what i meant is that i don't want "Installer" of a application, i keep my computer clean of random trash.
Id rather have already installed version, and download that, but that is my personal taste.

Regarding the installed game:

I installed the game. I run it, i see application window open for like 100miliseconds and then it closes without error...

Did you test the game you upload does it work?

Regarding the code:

If i couldn't open your project file. I would just open all the .cpp and .h/.hpp files and i would work with that in my editor instead of using the internet browser...

"I like to meat with fork, do you? i can eat it with spoon like you served me, but it would just bug me..."

I installed the game. I run it, i see application window open for like 100miliseconds and then it closes without error...
Did you test the game you upload does it work?

well that's a bummer. I actually did test it. It runs perfectly fine on my machine. Tested it on a friend's machine works fine on that as well. What OS are you running? I am using Windows 7 and my friend has Win8.

ok so I installed it on another machine that was running win8, and I had the exact same problem that you mentioned. The window would pop up and instantly close. I right clicked on the icon and clicked "Run as administrator" and now it runs perfectly fine. I have no idea why it's like this though. Maybe someone who has any idea can shed some light on this.

There is another problem that I have noticed running this game on different computers. This game was created on my laptop that I use for work, its a core I3 2.3 GHz, with 4gb ram and an integrated graphics card. This laptop has windows 7 and a ton of programs running on it with several running in the background. When I run the game on this the framerate can get quite choppy, going to down to as low as 4 or 5 FPS, which make the game rather unplayable on occasion. Usually it runs ok with a few slowdowns that are bearable. I have another laptop that is a core I5 2.6 GHZ with 4gb ram and an Nvidia GT 525M graphics card, it is running windows 8 and has hardly any programs installed on it. The game runs absolutely fine on this, no visible slowdowns whatsoever and is smooth as silk.

Can somebody explain to me why its like this. I would imagine a game like breakout should run very smoothly on any modern computer. I'm guessing its probably the way I am handling my timestep??? or probably something wrong with the way I am handling the movement of the paddle and ball in their respective update functions. I would appreciate it if somebody could have a look at that and let me know what I am doing wrong. I am currently already working on my next project which is going to be a pacman clone, and I would like to have problems like these sorted out before I finish that one. Thanks.

ok so I installed it on another machine that was running win8, and I had the exact same problem that you mentioned. The window would pop up and instantly close.

A exception has bean thrown and not handled properly is probably what is happening.

A exception has bean thrown and not handled properly is probably what is happening.

If that was the case then it would not have run at all. I think it has to do with how the user's rights have been set up. It requires elevated rights and privileges to run and as such runs only when you run the program as administrator. I've tried this on several machines now some of which don't have this problem at all and those that do the game runs when I run it as administrator.

This topic is closed to new replies.

Advertisement