While loop confusion - c++

Question:
My while loop is not exiting. During debugging it has says very specifically that stateID is equal to 3. However, when I add std::cout << stateID; the value 1 is always written to the console, no matter what the debugger is telling me.
In the code, I render the screen after the input loop. This shows that, without a doubt, the input loop exits properly, as expected. Also, if that is not enough, It would have to exit for the stateID to change in the first place. Please, no more discussion of the nested loop being the issue. And I have also used breakpoints after the loop which are properly hit.
Code:
int main()
{
stateID = 1;
GameState* state = new GameStateTitle();
sf::RenderWindow window(sf::VideoMode(1000, 600), "RPG");
//GAME LOOP//
while (stateID != 3)
{//INPUT//
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
//Window closed
case sf::Event::Closed:
set_next_state(3);
break;
}
}
change_state(state);
//RENDERING//
window.clear(sf::Color::Black);
state->render(window);
window.display();
}
/////////////
window.close();
return 0;
}
void set_next_state(int new_state)
{
//Set the next state to take place
next_state = new_state;
}
void change_state(GameState *current_state)
{
//Check if the next state is null or exit
if (next_state != 0)
{
if (next_state != 3)
delete current_state;
//Set the new state
switch(next_state)
...
}
stateID = next_state;
next_state = 0;
}
}
Below is my full code, in case I missed something important.
Main.cpp
#include "GameState.hpp"
int main()
{
stateID = STATE_TITLE;
GameState* state = new GameStateTitle();
sf::RenderWindow window(sf::VideoMode(1000, 600), "RPG");
//GAME LOOP//
while (stateID != STATE_EXIT)
{
//INPUT//
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
//Window closed
case sf::Event::Closed:
set_next_state(STATE_EXIT);
break;
}
}
///////////
////LOGIC//
state->logic();
///////////
change_state(state);
//RENDERING//
window.clear(sf::Color::Black);
state->render(window);
std::cout << stateID;
window.display();
/////////////
}
///////////////
window.close();
return 0;
}
GameState.hpp
#pragma once
#include <SFML/Graphics.hpp>
//DEFINITIONS ETC//
enum GAME_STATES {
STATE_NULL,
STATE_TITLE,
STATE_BATTLE,
STATE_EXIT
};
///////////////////
//Game State Class//
class GameState
{
public:
virtual void input(void) = 0;
virtual void logic(void) = 0;
virtual void render(sf::RenderWindow &window) = 0;
};
////////////////////
//FUNCTIONS//
void set_next_state(int new_state);
void change_state(GameState *current_state);
/////////////
//VARIABLES//
static int stateID;
static int next_state;
/////////////
//Title GameState Class//
class GameStateTitle : public GameState
{
private:
sf::Texture img_title;
sf::Sprite bgr_title;
public:
GameStateTitle(void);
~GameStateTitle(void);
void input(void);
void logic(void);
void render(sf::RenderWindow &window);
};
/////////////////////////
//Battle GameState Class//
class GameStateBattle : public GameState
{
private:
sf::Image img_left;
sf::Image img_right;
public:
GameStateBattle(void);
~GameStateBattle(void);
void input(void);
void logic(void);
void render(sf::RenderWindow &window);
};
//////////////////////////
GameState.cpp
#include "GameState.hpp"
//Game state general functions
void set_next_state(int new_state)
{
//Set the next state to take place
next_state = new_state;
}
void change_state(GameState *current_state)
{
//Check if the next state is null or exit
if (next_state != STATE_NULL)
{
if (next_state != STATE_EXIT)
delete current_state;
//Set the new state
switch(next_state)
{
case STATE_TITLE:
current_state = new GameStateTitle;
break;
case STATE_BATTLE:
current_state = new GameStateBattle;
break;
}
stateID = next_state;
next_state = STATE_NULL;
}
}
//The functions of the title state
GameStateTitle::GameStateTitle(void)
{
//Load texture
img_title.loadFromFile("title_screen.png");
//Set texture to background
bgr_title.setTexture(img_title);
}
GameStateTitle::~GameStateTitle(void)
{
}
void GameStateTitle::input(void)
{
}
void GameStateTitle::logic(void)
{
}
void GameStateTitle::render(sf::RenderWindow &window)
{
window.draw(bgr_title);
}
//The functions of the battle state
GameStateBattle::GameStateBattle(void)
{
}
GameStateBattle::~GameStateBattle(void)
{
}
void GameStateBattle::input(void)
{
}
void GameStateBattle::logic(void)
{
}
void GameStateBattle::render(sf::RenderWindow &window)
{
}

You have two while loops. The condition in the outer while will never be tested until the inner loop exits.
Consider using just one loop, with a single condition.
sf::Event event;
while ( (stateID != 3) && window.pollEvent(event)) {
}

You are breaking out of the switch and not out of the while.
The program below (attempts to) duplicate your code.
It works as expected, with both loops ending when they are supposed to.
Btw, this is what we call a short, contained, correct example.
Correct as in compilable, using globals such as stateID or magic numbers such as the 3 in while (stateID != 3) is bad form and not the mark of a professional.
How does your program deviate from the one below?
#define STATE_TITLE 2
#define STATE_BATTLE 3
#define STATE_NULL 0
int stateID;
int next_state;
struct Event
{
Event(int Num) : type(Num){}
Event() : type( 5 ){} // random number grater than 1
enum Type
{
Closed = 1 // equivalent to sf::Event::Closed
};
int type;
};
class Window
{
public:
int pollEvent( Event& Ev )
{
return --Ev.type;
}
};
void set_next_state(int new_state)
{
next_state = new_state;
}
void change_state()
{
if (next_state != STATE_NULL)
{
stateID = next_state;
next_state = STATE_NULL;
}
}
int _tmain()
{
stateID = STATE_TITLE;
Window window;
//GAME LOOP//
while (stateID != 3)
{//INPUT//
Event event;
// note that there is at least one event with a Closed type before window.pollEvent(event) return false (0)
while (window.pollEvent(event))
{
switch (event.type)
{
//Window closed
case Event::Closed:
set_next_state(3);
break;
}
}
change_state();
}
return 0;
}

I changed the function change_state to the following:
void change_state(GameState *current_state, int &ID)
{
//Check if the next state is null or exit
if (next_state != STATE_NULL)
{
if (next_state != STATE_EXIT)
delete current_state;
//Set the new state
switch(next_state)
{
case STATE_TITLE:
current_state = new GameStateTitle;
break;
case STATE_BATTLE:
current_state = new GameStateBattle;
break;
}
ID = next_state;
next_state = STATE_NULL;
}
}
The issue must've been within the declaration of stateID, because it was never being changed in this function.

Related

How to run rendering thread properly from class with function inside that class?

I have this error at my project with threads and I dont know how to solve it. I tryed std::thread and sf::Thread. Could someone help please?
Im creating Animation object inside main class and through function runThread() I am trying to launch thread inside the Animation class.
Error log:
Failed to activate the window's context
Failed to activate OpenGL context
My solution
Main class
int main()
{
bool launchThreads = true;
sf::RenderWindow window(sf::VideoMode( 800, 600), "Title" );
Animation* anima = new Animation(window);
sf::Event event;
while(window.isOpen())
{
while (window.pollEvent(event))
{
anima->handleEvent(event);
if (event.type == sf::Event::Closed)
{
delete anima;
anima = nullptr;
window.close();
}
}
window.clear(sf::Color::Black);
here I am trying to launch that thread:
if (launchThreads)
{
anima->runThread();
launchThreads = false;
}
window.display();
}
return 0;
}
Animation.h :
class Animation
{
private:
sf::RenderWindow& window;
sf::RectangleShape* rectPtr;
sf::Vector2f mousePos;
sf::Thread thread;
public:
Animation(sf::RenderWindow& window);
void handleEvent(sf::Event event);
void runThread();
void handleDraw();
~Animation();
};
and Animation.cpp :
Animation::Animation(sf::RenderWindow& window) : thread(&Animation::handleDraw, this), window(window),rectPtr(nullptr), mousePos()
{
//sf::Thread thea(&handleDraw);
//thread = thea;
rectPtr = new sf::RectangleShape;
rectPtr->setSize(sf::Vector2f(100, 100));
rectPtr->setFillColor(sf::Color::Red);
}
void Animation::handleEvent(sf::Event event)
{
switch (event.type)
{
case sf::Event::MouseMoved:
mousePos = window.mapPixelToCoords(sf::Vector2i(event.mouseMove.x, event.mouseMove.y));
break;
}
}
void Animation::runThread()
{
thread.launch();
}
void Animation::handleDraw()
{
for (size_t i = 0; i < 10; i++)
{
rectPtr->setPosition(i*110, 10);
if (rectPtr->getGlobalBounds().contains(mousePos))
{
rectPtr->setFillColor(sf::Color::Yellow);
}
else rectPtr->setFillColor(sf::Color::Red);
window.draw(*rectPtr);
}
}
Animation::~Animation()
{
thread.terminate();
delete rectPtr;
rectPtr = nullptr;
}
Solution:
Solved with moving function window.display(); inside handleDraw() and moving context there too by window.setActive(); App shows what it have to. But inside console there are still same errors.. Think I can Ignore them.

Can't draw sf::RectangleShape s stored in vector (Tetris clone)

I am trying to storesf::RectangleShape's into thestd::vectorand then draw each of them into thesf::RenderWindow.
Single rectangle shape is representing 1x1 tetromino and i would like to store it into the vector each time it reaches the bottom of the window. Then I would like to reset the position of the current tetromino to the default position.
I think I'm not even to able store it correctly. Each time the tetromino reaches the bottom it gives me this error message:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Bellow please find my current code. I just started working on it and already got stuck.
Definitions.h
#pragma once
// Point structure
struct Point
{
int dim_x;
int dim_y;
};
// Field Dimensions
const int fieldRows = 10;
const int fieldColumns = 9;
const int pointSize = 50.f;
// For checkingEdges funntion within the Tetrnomino.h
enum Edge
{
leftEdge,
rightEdge,
noneEdge
};
Game.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "Definitions.h"
#include "Tetromino.h"
class Game
{
public:
Game();
~Game();
// Game starter
void run();
// Accessors
bool running();
private:
// Updating and rendering the game window
void update();
void render();
// Initialization
void initVariables();
void initWindow();
void initBacgroundMusic();
// Polling
void pollEvents();
// Window logic stuff
sf::RenderWindow* _window;
sf::Event _event;
void drawStack();
// Bacground Music
sf::Music _ost;
// Tetromino + Its logic
Tetromino _T;
sf::Time delayTime = sf::milliseconds(300);
sf::Clock clock;
};
Tetromino.h
#pragma once
#include <SFML/Graphics.hpp>
#include <vector>
#include "Definitions.h"
class Tetromino
{
public:
Tetromino();
~Tetromino();
// Initialization
void initTetromino();
// Tetromonino logic
void moveTetromino();
Edge checkEdges();
// Getters & Setters
sf::RectangleShape getTetromino();
sf::RectangleShape getStackPart(int part);
int getStackSize();
void setTetromino(sf::RectangleShape &t);
private:
// The current tetromino
sf::RectangleShape _tetromino;
std::vector<sf::RectangleShape> _stack;
};
Game.cpp
#include "Game.h"
//-----Consturcotrs and Destructors-----//
Game::Game()
{
//Basic Initialization
_T.initTetromino();
initVariables();
}
Game::~Game()
{
delete _window;
}
//-----Private Functions-----//
void Game::run()
{
update();
render();
}
bool Game::running()
{
return _window->isOpen();
}
void Game::update()
{
sf::Time elapsed = clock.getElapsedTime();
pollEvents();
if (elapsed >= delayTime)
{
_T.moveTetromino();
clock.restart();
}
}
void Game::render()
{
_window->clear(sf::Color::White);
_window->draw(_T.getTetromino());
drawStack();
_window->display();
}
void Game::initVariables()
{
_window = nullptr;
initWindow();
initBacgroundMusic();
}
void Game::initWindow()
{
_window = new sf::RenderWindow(sf::VideoMode(fieldColumns * pointSize, fieldRows * pointSize), "Tetris v0.2", sf::Style::Default);
_window->setVerticalSyncEnabled(true);
_window->setFramerateLimit(60);
}
void Game::initBacgroundMusic()
{
_ost.openFromFile("../QT_SFML_Tetris/Music.ogg");
_ost.play();
_ost.setLoop(true);
_ost.setVolume(50.f);
}
void Game::pollEvents()
{
while (_window->pollEvent(_event))
{
if (_event.type == sf::Event::Closed) {_window->close();}
if (_event.type == sf::Event::KeyPressed)
{
if (_event.key.code == sf::Keyboard::Escape){_window->close();}
if (_event.key.code == sf::Keyboard::Left && _T.checkEdges() != leftEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x - pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Right && _T.checkEdges() != rightEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x + pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Down)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x, t.getPosition().y+ pointSize);
_T.setTetromino(t);
render();
}
}
}
}
**void Game::drawStack()**
{
for (unsigned int i = _T.getStackSize(); i > 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}
main.cpp
#include <Game.h>
int main()
{
Game game;
while (game.running())
{
game.run();
}
return 0;
}
Tetromino.cpp
#include "Tetromino.h"
//-----Consturcotrs and Destructors-----//
Tetromino::Tetromino()
{
}
Tetromino::~Tetromino()
{
}
//-----Public Functions-----//
void Tetromino::initTetromino()
{
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
_tetromino.setSize(sf::Vector2f(pointSize, pointSize));
_tetromino.setFillColor(sf::Color::Red);
}
void Tetromino::moveTetromino()
{
_tetromino.move(0.f, pointSize);
if (_tetromino.getPosition().y > fieldRows * pointSize - pointSize)
{
_stack.push_back(_tetromino);
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
}
}
Edge Tetromino::checkEdges()
{
if (_tetromino.getPosition().x == 0)
{
return leftEdge;
}
else if (_tetromino.getPosition().x == (fieldColumns * pointSize) - pointSize)
{
return rightEdge;
}
else return noneEdge;
}
sf::RectangleShape Tetromino::getTetromino()
{
return _tetromino;
}
sf::RectangleShape Tetromino::getStackPart(int part)
{
return _stack[part];
}
int Tetromino::getStackSize()
{
return _stack.size();
}
void Tetromino::setTetromino(sf::RectangleShape &t)
{
_tetromino = t;
}
I think the main issue could be within this line:
_stack.push_back(_tetromino);
In the drawStack() method you try to iterate backwards.
There is a reverse iterator doing this for you.
you have an off-by one error in your index calculation, which works only with an empty vector (exactly to prevent these errors you should use the iterator!)
You may want to read about iterators in C++ here is a small example.
According to your code it will look like (note that you need also a getStack()-method in Tetromino.hpp, returning the reference of the vector):
void Game::drawStack()
{
for (auto it = _T.getStack().rbegin(); it != _T.getStack().rend(); it++)
{
_window->draw(*it);
}
}
If you want to keep the index, I this is a fix:
void Game::drawStack()
{
for (int i = _T.getStackSize()-1; i >= 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}

C++/SFML Graphing Application-Repeating Texture/Sprite

I was taking up the challenge of creating a program to use for graphing simple math equations using C++ and the SFML 2.3.2. graphics library, and I've got the graph paper texture rendering fine. However, the problem I've had is getting it to repeat itself as I scroll around.
I was using sf::View to get it to pan, and it works well, but as soon as it pans outside the pre-defined size of the sprite it's just a blank background.
I thought of trying to determine when I'm outside the bounds of the sprite, and then expanding the size of the sprite or moving it, but then drawings (such as a graph) won't persist if the sprite is changed/reset.
What I need to know is how to create a background of a texture, in this case graphing paper, that will tile/repeat in every direction, and allow drawings to be made on top of it that persist if they move off screen.
Code is below:
GraphPaper.h:
#pragma once
#include "stdafx.h"
class GraphPaper
{
public:
GraphPaper();
~GraphPaper();
bool isObjectLoaded();
sf::Sprite getSprite();
private:
void load(std::string filename);
bool isLoaded;
sf::Texture texture;
sf::Sprite sprite;
const std::string file = "images/Graph-Paper.png";
};
GraphPaper.cpp: This is where I create and load the needed sprite and texture.
I set the texture to repeat inside the "load(string filename)" method, but that only affects it within the bounds set by the sprite's rectangle.
#include "GraphPaper.h"
GraphPaper::GraphPaper() : isLoaded(false)
{
load(file);
assert(isObjectLoaded());
}
GraphPaper::~GraphPaper() {};
void GraphPaper::load(std::string filename)
{
if (texture.loadFromFile(filename) == false)
isLoaded = false;
else
{
texture.setRepeated(true);
sprite.setTexture(texture);
//Huge size to at least make it look like it's infinite,
//but a temporary solution.
sprite.setTextureRect(sf::IntRect(0,0,10000,10000));
isLoaded = true;
}
}
bool GraphPaper::isObjectLoaded()
{
return isLoaded;
}
sf::Sprite GraphPaper::getSprite()
{
return sprite;
}
MainWindow.h:
#pragma once
#include "GraphPaper.h"
#include "stdafx.h"
class MainWindow
{
public:
void close();
void start();
void moveCamera(sf::Event);
private:
bool leftMousePressed, rightMousePressed, isExiting;
int r, g, b, mouseX, mouseY;
GraphPaper paper;
const sf::Color white = sf::Color(255, 255, 255);
sf::RenderWindow mainWindow;
sf::View view;
};
MainWindow.cpp: This is what handles all the drawing, and, at the moment, all input processing. "start()" is simply called from the main method.
#include "MainWindow.h"
#include "GraphPaper.h"
#include "stdafx.h"
void MainWindow::start()
{
sf::RectangleShape rectangle = sf::RectangleShape(sf::Vector2f(120, 50));
rectangle.setFillColor(sf::Color(0,0,0));
mainWindow.create(sf::VideoMode(1024, 768, 32), "Test");
sf::View view(sf::FloatRect(0,0,1000,600));
mainWindow.setView(view);
leftMousePressed, rightMousePressed, isExiting = false;
sf::Event currentEvent;
mainWindow.clear(white);
mainWindow.draw(paper.getSprite());
mainWindow.display();
while (!isExiting)
{
while (mainWindow.pollEvent(currentEvent))
{
switch (currentEvent.type)
{
case sf::Event::MouseMoved:
{
if (rightMousePressed == true)
{
std::cout << "Mouse Panned\n";
}
if (leftMousePressed == true)
{
std::cout << "Mouse is Drawing\n";
}
break;
}
case sf::Event::MouseButtonPressed:
{
std::cout << "Mouse Pressed\n";
mouseX = currentEvent.mouseButton.x;
mouseY = currentEvent.mouseButton.y;
if (currentEvent.mouseButton.button == sf::Mouse::Left)
{
leftMousePressed = true;
}
else if (currentEvent.mouseButton.button == sf::Mouse::Right)
{
rightMousePressed = true;
}
break;
}
case sf::Event::MouseButtonReleased:
{
std::cout << "Mouse Released\n";
if (currentEvent.mouseButton.button == sf::Mouse::Left)
{
leftMousePressed = false;
}
else if(currentEvent.mouseButton.button == sf::Mouse::Right)
{
rightMousePressed = false;
}
break;
}
case sf::Event::KeyPressed:
{
if (currentEvent.key.code == sf::Keyboard::Escape)
{
close();
}
//No right movement yet, was testing.
else if (currentEvent.key.code == sf::Keyboard::Left)
{
moveCamera(currentEvent);
}
break;
}
case sf::Event::Closed:
{
close();
break;
}
}
}
}
}
void MainWindow::moveCamera(sf::Event key)
{
std::cout << "Inside moveCamera\n";
//No right movement yet, was testing.
//Movement is also hardcoded for testing as well.
view.move(100, 0);
mainWindow.setView(view);
mainWindow.clear(white);
mainWindow.draw(paper.getSprite());
mainWindow.display();
std::cout << "Leaving moveCamera\n";
}
void draw()
{
//mainWindow.draw();
}
void MainWindow::close()
{
std::cout << "Closing...\n";
mainWindow.close();
isExiting = true;
}

SFML VideoMode breaks application

Using SFML sf::VideoMode breaks my application, saying that "Singularity.exe has stopped working"
Specifically this line :
_mainWindow.create(sf::VideoMode(1024,768,32), "Singularity");
This line is what is causing the problem. When I remove it, the application works fine. Here is the whole code of the main class file:
#include "stdafx.h"
#include "Game.h"
void Game::Start(void)
{
if (_gameState != Uninitialized)
return;
_mainWindow.create(sf::VideoMode(1024,768,32), "Singularity");
_gameState = Game::Playing;
while (!IsExiting())
{
GameLoop();
}
_mainWindow.close();
}
bool Game::IsExiting()
{
if (_gameState == Game::Exiting)
return true;
else
return false;
}
void Game::GameLoop()
{
sf::Event currentEvent;
while (_mainWindow.pollEvent(currentEvent))
{
switch (_gameState)
{
case Game::Playing:
{
_mainWindow.clear(sf::Color(255, 0, 0));
_mainWindow.display();
if (currentEvent.type == sf::Event::Closed)
{
_gameState = Game::Exiting;
}
break;
}
}
}
}
Game::GameState Game::_gameState = Uninitialized;
sf::RenderWindow Game::_mainWindow;
Does anyone have any idea of what might be causing this or how to fix it? I am completely new to SFML, so I'm at a loss for what to do.
Thanks, Zuve

Game Launches to a blank white screen instead of loadingscreen

Trying to create a game but i've run into my first hurdle. The game launches into a blank white screen instead of showing the Red screen and i cant proceed into the loading screen and the menu. I've checked that I'm using display for each of my screens but can't figure out where i'm going wrong. I also get no errors. Below is my code
game.cpp
#include "stdafx.h"
#include "Game.h"
#include "LoadScreen.h"
#include "MainMenu.h"
void Game::Start (void)
{
Game game;
if(_gameState != Unlaunched)
return;
game._mainWindow.create(sf::VideoMode(1024,768,32),"Code Matrix");
_gameState = Game::LogoScreen;
while (!Exists())
{
GameLoop();
}
game._mainWindow.close();
}
bool Game::Exists()
{
if(_gameState == Game::Exiting)
return true;
else
return false;
}
void Game::GameLoop()
{
Game game;
sf::Event currentEvent;
while (game._mainWindow.pollEvent(currentEvent))
{
switch (_gameState)
{
case Game::MenuWindow:
{
ShowMenu();
break;
}
case Game::LogoScreen:
{
ShowLogoScreen();
break;
}
case Game::Playing:
{
sf::Event currentEvent;
while (game._mainWindow.pollEvent(currentEvent))
{
game._mainWindow.clear(sf::Color(255,0,0));
game._mainWindow.display();
if(currentEvent.type == sf::Event::Closed)
_gameState = Game::Exiting;
if(currentEvent.type == sf::Event::KeyPressed)
{
if(currentEvent.key.code == sf::Keyboard::Escape) ShowMenu();
}
}
break;
}
}
}
}
void Game::ShowLogoScreen()
{
Game game;
LoadScreen loadScreen;
loadScreen.Show(game._mainWindow);
_gameState = Game::MenuWindow;
}
void Game::ShowMenu()
{
Game game;
MainMenu mainMenu;
MainMenu::MenuOption option = mainMenu.show(game._mainWindow);
switch(option)
{
case MainMenu::Exit:
_gameState = Game::Exiting;
break;
case MainMenu::Play:
_gameState = Game::Playing;
break;
}
}
Game::GameState Game::_gameState = Unlaunched;
LoadScreen.cpp
#include "stdafx.h"
#include "LoadScreen.h"
void LoadScreen::Show(sf::RenderWindow & renderWindow)
{
sf::Texture image;
if (image.loadFromFile("images/LoadingScreen.png") !=true)
{
return;
}
sf::Sprite sprite (image);
renderWindow.draw(sprite);
renderWindow.display();
sf::Event event;
while (true)
{
while (renderWindow.pollEvent(event))
{
if(event.type == sf::Event::EventType::KeyPressed
||event.type == sf::Event::EventType::MouseButtonPressed
|| event.type == sf::Event::EventType::Closed)
{
return;
}
}
}
}
MainMenu.cpp
#include "stdafx.h"
#include "MainMenu.h"
MainMenu::MenuOption MainMenu::show(sf::RenderWindow& window)
{
//Load menu image from file
sf::Texture image;
image.loadFromFile("images/MainMenu.png");
sf::Sprite sprite(image);
//Setup clickable regions
//Play menu item coordinates
MenuItem playButton;
playButton.rect.top= 319;
playButton.rect.height = 626;
playButton.rect.left = 189;
playButton.rect.width = 329;
playButton.action = Play;
//Options menu item coordinates
MenuItem optionButton;
optionButton.rect.left = 356;
optionButton.rect.height = 596;
optionButton.rect.top = 287;
optionButton.rect.width = 483;
optionButton.action = Options;
//Exit menu item coordinates
MenuItem exitButton;
exitButton.rect.left = 554;
exitButton.rect.height = 580;
exitButton.rect.top = 318;
exitButton.rect.width = 687;
exitButton.action = Exit;
_menuItems.push_back(playButton);
_menuItems.push_back(exitButton);
window.draw(sprite);
window.display();
return GetMenuAction(window);
}
MainMenu::MenuOption MainMenu::HandleClick(int x, int y)
{
std::list<MenuItem>::iterator it;
for ( it = _menuItems.begin(); it != _menuItems.end(); it++)
{
sf::Rect<int> menuItemRect = (*it).rect;
if( menuItemRect.height > y
&& menuItemRect.top < y
&& menuItemRect.left < x
&& menuItemRect.width > x)
{
return (*it).action;
}
}
return null;
}
MainMenu::MenuOption MainMenu::GetMenuAction(sf::RenderWindow& window)
{
sf::Event menuEvent;
while(true)
{
while(window.pollEvent(menuEvent))
{
if(menuEvent.type == sf::Event::MouseButtonPressed)
{
return HandleClick(menuEvent.mouseButton.x,menuEvent.mouseButton.y);
}
if(menuEvent.type == sf::Event::Closed)
{
return Exit;
}
}
}
}
void Game::ShowLogoScreen()
{
Game game; // <- this creates a NEW game. You want to use your already created game.
LoadScreen loadScreen;
loadScreen.Show(game._mainWindow);
_gameState = Game::MenuWindow;
}
You create a new game local to the logo screen. That one probably does not even own a window. You should reference your existing game variable.