Focus sprite by leftclick and then remove focus by leftclick again. (C++ and SFML 2.2) - c++

In the following code a sprite can by clicked with left mouse button and then moved around freely. Then you have to hit the right button to "free" it again.
Now what is, if I want to use left button for removing the focus, instead of right button. Is this possible and how? I can't imagine, how to do it. Many thanks in advance.
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
int main()
{
sf::RenderWindow mMainWindow(sf::VideoMode(600,600), "Map", sf::Style::Close);
mMainWindow.setFramerateLimit(60);
mMainWindow.setKeyRepeatEnabled(false);
sf::Image image;
image.create(50, 50, sf::Color::Red);
sf::Texture texture;
texture.loadFromImage(image);
std::vector<sf::Sprite> EnemyVector;
sf::Sprite* focus = nullptr;
bool move = false;
while (mMainWindow.isOpen())
{
sf::Event event;
bool creating = false;
bool leftclicked = false;
bool rightclicked = false;
sf::Vector2i mousePos;
while (mMainWindow.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
mMainWindow.close();
break;
case sf::Event::KeyPressed:
creating = (event.key.code == sf::Keyboard::A);
break;
case sf::Event::MouseButtonPressed:
if (event.mouseButton.button == sf::Mouse::Left)
{
leftclicked = true;
mousePos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
break;
}
if (event.mouseButton.button == sf::Mouse::Right)
{
rightclicked = true;
mousePos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
break;
}
}
}
if (creating)
{
sf::Sprite sprite;
mousePos = (mousePos == sf::Vector2i(0, 0) ? sf::Mouse::getPosition(mMainWindow) : mousePos);
sprite.setTexture(texture);
sprite.setColor(sf::Color::Red);
sprite.setOrigin(static_cast<float>(sprite.getTextureRect().width) / 2, static_cast<float>(sprite.getTextureRect().height) / 2);
sprite.setPosition(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y));
focus=nullptr;
EnemyVector.push_back(sprite);
}
if (leftclicked)
{
for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
{
if (enemy->getGlobalBounds().contains(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)))
{
focus = &(*enemy);
move = true;
break;
}
}
}
if(rightclicked)
{
focus = nullptr;
}
if(move)
{
if(focus!=nullptr)
{
focus->move((sf::Mouse::getPosition(mMainWindow).x - focus->getPosition().x),(sf::Mouse::getPosition(mMainWindow).y - focus->getPosition().y));
}
}
mMainWindow.clear();
for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
{
mMainWindow.draw(*enemy);
}
mMainWindow.display();
}
return 0;
}

try this
if (leftclicked)
{
for (auto& enemy = EnemyVector.rbegin(); enemy != EnemyVector.rend(); ++enemy)
{
if (enemy->getGlobalBounds().contains(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)))
{
focus = &(*enemy);
move = !move;
break;
}
}
}

Related

Problems with getPosition() in SFML

I'm new to c++ so I'm a bit confused on this one. I'm trying to have the player spawn, then when the user presses "C", the player switches with a car. What's happening currently is the player is initially spawning in the correct location, then the car is spawning where the player initially spawned, not where it currently is. However, since I'm using the function getPosition(), I would assume it would spawn in the current position of the player.
Player.h:
#pragma once
#include <SFML\Graphics.hpp>
#include <string>
class player {
public:
sf::Texture normalTexture;
sf::Sprite normalSprite;
sf::Texture carTexture;
sf::Sprite carSprite;
sf::Texture springTexture;
sf::Sprite springSprite;
sf::Texture rocketTexture;
sf::Sprite rocketSprite;
sf::IntRect normalRect[1];
sf::IntRect carRect[1];
sf::IntRect springRect[1];
sf::IntRect rocketRect[1];
bool rocket=false;
bool car=false;
bool spring=false;
bool normal=false;
player();
player(sf::Vector2f position, std::string normalFileLoc, std::string carFileLoc, std::string springFileLoc, std::string rocketFileLoc);
void update();
};
Player.cpp:
#include "Player.h"
player::player() : player::player(sf::Vector2f(100, 0), "player.jpg", "car.png", "spring.png", "rocket.png") {
}
player::player(sf::Vector2f position, std::string normalFileLoc, std::string
carFileLoc, std::string springFileLoc, std::string rocketFileLoc)
{
normalTexture.loadFromFile(normalFileLoc);
normalRect[0] = sf::IntRect(0, 0, 64, 128);
normalSprite.setTexture(normalTexture);
normalSprite.setTextureRect(normalRect[0]);
normalSprite.setOrigin(0,0);
normalSprite.setScale(1, 1);
normalSprite.setPosition(position.x, position.y);
carTexture.loadFromFile(carFileLoc);
carRect[0] = sf::IntRect(0, 0, 64, 64);
carSprite.setTexture(carTexture);
carSprite.setTextureRect(carRect[0]);
carSprite.setOrigin(0, -64);
carSprite.setScale(1, 1);
carSprite.setPosition(normalSprite.getPosition().x, normalSprite.getPosition().y);
}
Main.cpp I know it looks gross, I plan on making it look nicer later:
#include <SFML/Graphics.hpp>
#include <SFML\Graphics\Rect.hpp>
#include "player.h"
int main()
{
sf::RenderWindow window(sf::VideoMode(750, 750), "SFML Works!");
player thePlayer;
const float gravity = .001;
int groundheight = 500;
sf::Vector2f velocity(sf::Vector2f(0, 0));
thePlayer.normal = true;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed)
{
if (thePlayer.car && event.key.code == sf::Keyboard::C)
{
thePlayer.car = false;
thePlayer.spring = false;
thePlayer.rocket = false;
thePlayer.normal = true;
break;
}
if (thePlayer.spring && event.key.code == sf::Keyboard::S)
{
thePlayer.car = false;
thePlayer.spring = false;
thePlayer.rocket = false;
thePlayer.normal = true;
break;
}
if (thePlayer.rocket && event.key.code == sf::Keyboard::R)
{
thePlayer.car = false;
thePlayer.spring = false;
thePlayer.rocket = false;
thePlayer.normal = true;
break;
}
if (event.key.code == sf::Keyboard::C)
{
thePlayer.car = true;
thePlayer.spring = false;
thePlayer.rocket = false;
thePlayer.normal = false;
break;
}
if (event.key.code == sf::Keyboard::R)
{
thePlayer.car = false;
thePlayer.spring = false;
thePlayer.rocket = true;
thePlayer.normal = false;
break;
}
if (event.key.code == sf::Keyboard::S)
{
thePlayer.car = false;
thePlayer.spring = true;
thePlayer.rocket = false;
thePlayer.normal = false;
break;
}
}
}
if (thePlayer.normal)
{
velocity.x = 0;
thePlayer.normalSprite.move(velocity.x, velocity.y);
if (thePlayer.normalSprite.getPosition().y < groundheight)
{
velocity.y += gravity;
}
else
{
thePlayer.normalSprite.setPosition(thePlayer.normalSprite.getPosition().x, groundheight);
velocity.y = 0;
}
}
if (thePlayer.car)
{
thePlayer.carSprite.move(velocity.x, velocity.y);
if (thePlayer.carSprite.getPosition().y < groundheight)
{
velocity.y += gravity;
}
else
{
thePlayer.carSprite.setPosition(thePlayer.carSprite.getPosition().x, groundheight);
velocity.y = 0;
}
}
window.clear();
if (thePlayer.normal)
{
window.draw(thePlayer.normalSprite);
}
if (thePlayer.car)
{
window.draw(thePlayer.carSprite);
}
window.display();
}
}
Thanks so much!
Before drawing the car you should adjust its position to your player position :
if (thePlayer.car)
{
thePlayer.carSprite.setPosition(thePlayer.normalSprite.getPosition());
window.draw(thePlayer.carSprite);
}
But as ractiv said, you should organize your code differently. I suggest you to learn more about c++ "good pratices" before trying to do this kind of games.
We miss the main function to know exactly what happens when the car spawns but I think that you initialize the car in the Player constructor and does not move it when the player presses 'C'.
You should have something like that :
if(event.key.code == sf::Keyboard::C) {
player.spawnCar();
}
and in your spawnCar() function :
carSprite.setPosition(normalSprite.getPosition());
EDIT
As I said in my comment, you should use getters and setters to access to your attributes. According to your current main.cpp, you should have this :
if (event.key.code == sf::Keyboard::C)
{
thePlayer.car = true;
thePlayer.spring = false;
thePlayer.rocket = false;
thePlayer.normal = false;
carSprite.setPosition(normalSprite.getPosition());
break;
}

SFML/C++ Sprite Disappearing After Certain Point

int main() {
sf::RenderWindow window;
sf::Vector2i centerWindow((sf::VideoMode::getDesktopMode().width / 2) - 445, (sf::VideoMode::getDesktopMode().height / 2) - 480);
window.create(sf::VideoMode(900, 900), "SFML Game", sf::Style::Titlebar | sf::Style::Close);
window.setPosition(centerWindow);
window.setKeyRepeatEnabled(true);
sf::Texture wallTxture;
sf::Sprite wall;
if (!wallTxture.loadFromFile("wall.png")) {
std::cerr << "Error\n";
}
wall.setTexture(wallTxture);
//Gravity Vars:
int groundHeight = 750;
bool isJumping = false;
//Movement Vars:
bool goingRight = false;
bool goingLeft = false;
//Set View Mode:
sf::View followPlayer;
followPlayer.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
Player player("newPlayer.png");
player.setPos({ 800, 800 });
sf::Vector2f position(window.getSize().x / 2, window.getSize().y / 2);
//Main Loop:
while (window.isOpen()) {
const float moveSpeed = 0.1;
sf::Event Event;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
isJumping = true;
//Handle Movement While Jumping:
if (goingLeft == true) {
player.move({ -moveSpeed, -moveSpeed });
}
else if (goingRight == true) {
player.move({ moveSpeed, -moveSpeed });
}
else {
player.move({ 0, -moveSpeed });
}
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
player.move({ 0, moveSpeed });
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
player.move({ -moveSpeed, 0 });
goingLeft = true;
player.flipX('l');
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
player.move({ moveSpeed, 0 });
goingRight = true;
player.flipX('r');
}
//Event Loop:
while (window.pollEvent(Event)) {
switch (Event.type) {
case sf::Event::Closed:
window.close();
case sf::Event::KeyReleased:
if (Event.key.code == sf::Keyboard::Up) {
isJumping = false;
}
else if (Event.key.code == sf::Keyboard::Left) {
goingLeft = false;
}
else if (Event.key.code == sf::Keyboard::Right) {
goingRight = false;
}
}
}
if (player.getX() > window.getSize().x) {
position.x = player.getX();
}
else {
position.x = window.getSize().x;
}
//If player is in air and not jumping:
if (player.getY() < groundHeight && isJumping == false) {
player.move({ 0, moveSpeed });
}
followPlayer.setCenter(position);
window.clear();
window.setView(followPlayer);
window.draw(wall);
player.drawTo(window);
window.display();
}
}
this is my code. What I am trying to do is create a 2D platformer sidescroller. Everything works, except when the sprite goes past a certain point it'll just disappear. This also happens when I jump and move through the air at the same time. I cannot figure out why this is happening, any help would be greatly appreciated :)
I fixed the problem by just getting rid of my flipX function, and instead just creating a new sprite facing a different direction, then changing it everytime the user is facing a new direction

RenderWindow Constantly Updating display() Causing Flickering

I am trying to write a program which allows users to draw using the mouse. I have been trying many different ways to appropriately update the display using an object of sf::RenderWindow to call display() without much success. My loop where the drawing is occurring is calling display so fast it's causing massive flickering (confirmed that through testing). If I add a way to slow the call to display(), like using sf::Clock, then the drawing is only updated on the same delay as display() resulting in a stuttering effect. What I need is a way to update the display often enough to show drawing updates while also not causing a screen flicker.
Currently, I've got the display on a delay (at the bottom of the event polling switch statement) so flickering doesn't occur, but adding mainWindow.display(); to the void MainWindow::draw() function causes flickering as it updates too quickly. I had the drawing occurring on sf::Event::MouseMoved, but I tried changing it to see if that would help, and it did not.
Here's where all the drawing and event detection occurs:
MainWindow.h
#pragma once
#include "GraphPaper.h"
#include "stdafx.h"
class MainWindow
{
public:
MainWindow(short, short);
void close();
void start();
void moveCamera(sf::Keyboard::Key);
void draw(sf::Event);
void displayWindow(sf::Vector2i&);
private:
bool leftMousePressed, rightMousePressed, isExiting;
int r, g, b, mouseX, mouseY;
short height, width;
const short DRAWING_CRICLE_RADIUS = 10;
GraphPaper paper;
//DrawingBrush brush;
const sf::Color WHITE = sf::Color(255, 255, 255);
const sf::Color BLACK = sf::Color(0, 0, 0);
sf::CircleShape circle;
sf::Mouse cursor;
sf::Vector2i windowCenter;
sf::RenderWindow mainWindow;
sf::View view;
};
MainWindow.cpp:
#include "MainWindow.h"
#include "GraphPaper.h"
#include "stdafx.h"
MainWindow::MainWindow(short height, short width)
{
this->height = height;
this->width = width;
circle.setRadius(DRAWING_CRICLE_RADIUS);
circle.setFillColor(BLACK);
}
void MainWindow::start()
{
sf::Clock clock;
mainWindow.create(sf::VideoMode(height, width, 32), "Test");
sf::View view(sf::FloatRect(0,0,height,width));
mainWindow.setView(view);
leftMousePressed, rightMousePressed, isExiting = false;
sf::Event currentEvent;
sf::Vector2i windowCenter(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));
displayWindow(windowCenter);
while (!isExiting)
{
sf::Clock clock;
while (mainWindow.pollEvent(currentEvent))
{
switch (currentEvent.type)
{
case sf::Event::MouseMoved:
{
if (rightMousePressed == true)
{
std::cout << "Mouse Panned\n";
}
if (leftMousePressed == true)
{
draw(currentEvent);
}
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)
{
while (currentEvent.type != sf::Event::MouseButtonReleased)
{
std::cout << "Mouse is Drawing\n";
draw(currentEvent);
mainWindow.pollEvent(currentEvent);
}
}
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:
{
sf::Keyboard::Key keyPressed = currentEvent.key.code;
if(keyPressed == sf::Keyboard::Escape)
{
close();
}
else if(keyPressed == sf::Keyboard::Left || sf::Keyboard::Right ||
sf::Keyboard::Down || sf::Keyboard::Up ||
sf::Keyboard::A || sf::Keyboard::S ||
sf::Keyboard::D || sf::Keyboard::W)
{
moveCamera(keyPressed);
displayWindow(windowCenter);
}
break;
}
case sf::Event::Closed:
{
close();
break;
}
case sf::Event::Resized:
{
windowCenter = sf::Vector2i(mainWindow.getPosition().x + (mainWindow.getSize().x / 2), mainWindow.getPosition().y + (mainWindow.getSize().y / 2));
displayWindow(windowCenter);
break;
}
}
if (clock.getElapsedTime().asMilliseconds() >= 500)
{
clock.restart();
mainWindow.display();
}
}
}
}
void MainWindow::moveCamera(sf::Keyboard::Key keyPressed)
{
view = mainWindow.getView();
switch (keyPressed)
{
case sf::Keyboard::A:
case sf::Keyboard::Left:
{
view.move(-50, 0);
break;
}
case sf::Keyboard::D:
case sf::Keyboard::Right:
{
view.move(50, 0);
break;
}
case sf::Keyboard::W:
case sf::Keyboard::Up:
{
view.move(0, 50);
break;
}
case sf::Keyboard::S:
case sf::Keyboard::Down:
{
view.move(0, -50);
break;
}
}
mainWindow.setView(view);
}
void MainWindow::draw(sf::Event mouse)
{
circle.setPosition(mainWindow.mapPixelToCoords(sf::Vector2i(mouse.mouseMove.x, mouse.mouseMove.y)));
mainWindow.draw(circle);
}
void MainWindow::close()
{
std::cout << "Closing...\n";
mainWindow.close();
isExiting = true;
}
void MainWindow::displayWindow(sf::Vector2i& windowCenter)
{
mainWindow.clear(WHITE);
mainWindow.draw(paper.getSprite());
mainWindow.display();
cursor.setPosition(windowCenter);
}
You are missing an important part of the rendering loop. You should draw all parts every loop iteration. Right now you are only drawing your circle when it's changed.
Your code should look like this:
change circle position based on input
clear window
draw circle
display

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

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.