Background Image overlapping Main Menu Items - c++

I just started learning Game Development recently. I managed to develop a simple game (something like Space Shooters) and a simple start menu using C++ and SFML. (THIS IS NOT HOMEWORK)
Problem: The background image for the Main Menu screen overlaps my text/menu items. But the background image for the Game Screen does not overlap my game items.
Relevant codes:
main.cpp
int main()
{
//Background Image for Game Screen
sf::Texture galaxyBackgroundTexture, menuBackgroundTexture;
sf::Sprite galaxyBackground, menuBackground;
sf::Vector2u TextureSize; //Added to store texture size.
sf::Vector2u WindowSize; //Added to store window size.
sf::RenderWindow window(sf::VideoMode(1200, 800), "Space Invader Team 62");
if (!galaxyBackgroundTexture.loadFromFile("Textures/galaxy_background.png"))
{
cout << "Failed to load Image" << endl;
}
else
{
TextureSize = galaxyBackgroundTexture.getSize(); //Get size of texture
WindowSize = window.getSize(); //Get size of window
float ScaleX = (float)WindowSize.x / TextureSize.x;
float ScaleY = (float)WindowSize.y / TextureSize.y; //Calculate scale
galaxyBackground.setTexture(galaxyBackgroundTexture);
galaxyBackground.setScale(ScaleX, ScaleY); //Set scale
}
// Menu
menuBackground.setTexture(menuBackgroundTexture);
Menu menu(window.getSize().x, window.getSize().y);
GameObjectManager* gameObjectManagerManager = nullptr;
bool inGame = false; //true = game has started, false = menu screen
// window.setFramerateLimit(144);
while (window.isOpen()) // main loop
{
sf::Event event;
while (window.pollEvent(event)) // event loop
{
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Return)
{
if (!inGame)
{
cout << "Play button has been pressed." << endl;
inGame = true;
gameObjectManagerManager = new GameObjectManager(&window);
}
}
if (event.type == sf::Event::Closed) window.close();
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) window.close();
}
//this is the place where you call your updates
if (inGame) gameObjectManagerManager->update();
window.clear();
if (!inGame)menu.draw(window);
{
window.draw(menuBackground);
}
if (inGame)
{
window.draw(galaxyBackground);
gameObjectManagerManager->render(window);
}
window.display();
}
return 0;
}

Your background image is drawn after the items. You need to draw them in the correct order.
Change this:
if (!inGame)menu.draw(window);
{
window.draw(menuBackground);
}
TO THIS:
if (!inGame)
{
window.draw(menuBackground);
menu.draw(window);
}

Related

button in cpp sfml lib don't respond to my mouse input

I have to make Quarto game as a GUI program so firstly I wanted to make buttons in menu, but I don't know why it don't fill color when my mouse is at the button.
Code:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include<bits/stdc++.h>
using namespace std;
using namespace sf;
class button{
public:
bool isClicked=false;
int Yposition;
int Xposition;
bool isMouseOn=false;
};
int main(){
//Defining variables
Vector2i mouseWindowPosition;
//rendering window "window"
RenderWindow window(VideoMode(800,600), "Quarto game - menu", Style::Default);
window.display();
//setting vsync
window.setVerticalSyncEnabled(true);
//loading textures
Texture backgroundTexture;
backgroundTexture.loadFromFile("Resources/background.png");
//making sprites
Sprite backgroundSprite;
backgroundSprite.setTexture(backgroundTexture);
backgroundSprite.setPosition(0,0);
//making buttons and their colors
RectangleShape playButton(Vector2f(200.f,50.f));
playButton.setFillColor(Color(128,128,128));
playButton.setOutlineThickness(5.f);
playButton.setOutlineColor(Color(100,100,100));
button play;
//setting position of buttons
play.Xposition=70;
play.Yposition=200;
//game loop
while(window.isOpen()){
Event event;
playButton.setFillColor(Color(128,128,128));
play.isMouseOn=false;
while(window.pollEvent(event)){
if(event.type==Event::Closed){
window.close();
}
}
//Getting mouse position
mouseWindowPosition=Mouse::getPosition(window);
if(mouseWindowPosition.x<=play.Xposition && mouseWindowPosition.y<=play.Yposition && mouseWindowPosition.x>=play.Xposition+200 && mouseWindowPosition.y>=play.Yposition+50){
play.isMouseOn=true;
}
//Drawing to screen
window.clear();
window.draw(backgroundSprite);
if(play.isClicked==false){
playButton.setPosition(Vector2f(play.Xposition, play.Yposition));
window.draw(playButton);
}
if(play.isMouseOn==true){
playButton.setFillColor(Color(128,128,128));
}
window.display();
}
}
Is there any better way to make buttons in sfml?
The immediate reason why the button doesn't fill is your if the statement has the signs reversed for checking the box. Using this if statement instead should work:
//Getting mouse position
mouseWindowPosition=Mouse::getPosition(window);
if (mouseWindowPosition.x>=play.Xposition && mouseWindowPosition.y>=play.Yposition &&
mouseWindowPosition.x<=play.Xposition+200 && mouseWindowPosition.y<=play.Yposition+50){
//your code here
}
If you are not already aware, the x and y values are arranged like a table where positive y goes down instead of a cartesian coordinate system where positive y is up.
The other problem is the color you are updating your fill with is the same color of the fill, so changing that color will get you your desired fill.
Also, logic wise you should swap the statement
if (play.isMouseOn == true)
{
}
with the statement
if (play.isClicked == false)
{
playButton.setPosition(Vector2f(play.Xposition, play.Yposition));
window.draw(playButton);
window.display();
}
Here is a working code that changes the fill from grey to red when you hover above it:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
using namespace std;
using namespace sf;
class button
{
public:
bool isClicked = false;
int Yposition;
int Xposition;
bool isMouseOn = false;
};
int main()
{
//Defining variables
Vector2i mouseWindowPosition;
//rendering window "window"
RenderWindow window(VideoMode(800, 600), "Quarto game - menu", Style::Default);
window.display();
//setting vsync
window.setVerticalSyncEnabled(true);
//loading textures
Texture backgroundTexture;
backgroundTexture.loadFromFile("Resources/background.png");
//making sprites
Sprite backgroundSprite;
backgroundSprite.setTexture(backgroundTexture);
backgroundSprite.setPosition(0, 0);
//making buttons and their colors
RectangleShape playButton(Vector2f(200.f, 50.f));
playButton.setFillColor(Color(100, 100, 100));
playButton.setOutlineThickness(5.f);
playButton.setOutlineColor(Color(100, 100, 100));
button play;
//setting position of buttons
play.Xposition = 70;
play.Yposition = 200;
//game loop
while (window.isOpen())
{
Event event;
playButton.setFillColor(Color(128, 128, 128));
play.isMouseOn = false;
while (window.pollEvent(event))
{
if (event.type == Event::Closed)
{
window.close();
}
}
//Getting mouse position
mouseWindowPosition = Mouse::getPosition(window);
if (mouseWindowPosition.x >= play.Xposition && mouseWindowPosition.y >= play.Yposition && mouseWindowPosition.x <= play.Xposition + 200 && mouseWindowPosition.y <= play.Yposition + 50)
{
play.isMouseOn = true;
}
//Drawing to screen
window.clear();
window.draw(backgroundSprite);
if (play.isMouseOn == true)
{
playButton.setFillColor(Color(128, 0, 0));
}
if (play.isClicked == false)
{
playButton.setPosition(Vector2f(play.Xposition, play.Yposition));
window.draw(playButton);
window.display();
}
}
}

Double clicking in SFML doesnt work as expected

I am working on a recreation of minesweeper using cpp and SFML. I have coded the board and the tiles switch to their revealed states when you left click on them, however, I am running into a strange issue with the right click.
Since I want to be able to flag and unflag tiles, I created a texture called tile_foreground that stores a texture the same size as the tiles but is completely transparent. The idea is that the first click will flag the tile and draw the flag sprite and a 2nd click would unflag the tile and change the sprite texture to the empty png so that only the base of the tile shows, with the cycle continuing on further clicks.
When you right click, the first click wont register and it will take at least a 2nd click to place down a flag on the tile. Sometimes it takes more than 2 clicks and clicking on a tile, moving your mouse to a different tile and then back to the same tile without clicking on a different tile will not flag the tile. It seems that the program doesnt register the first click as a click and waits for another one from the same tile to register it.
I suspect this comes from the way I handle the clicking events since before I added the statement below, holding down the right button would make the sprites alternate quickly and infinitely.
event.type == sf::Event::MouseButtonReleased
Any input would be appreciated since I dont really know how I would fix this.
Below is my main.cpp file
#include <SFML/Graphics.hpp>
#include <random>
#include <iostream>
#include <fstream>
#include <string>
#include "Board.h"
#include "TextureManager.h"
void testFunc() {
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
}
void loadMSImages() {
string files[21] = {"debug", "digits", "face_happy", "face_lose", "face_win", "flag", "mine",
"number_1", "number_2", "number_3" , "number_4" , "number_5" , "number_6",
"number_7" , "number_8", "test_1", "test_2", "test_3", "tile_hidden", "tile_revealed", "tile_foreground"};
for (int i = 0; i < 21; i += 1) {
TextureManager::LoadTexture(files[i]);
}
}
int main()
{
loadMSImages();
//testFunc(); // Test function to see if program is still working properly
// Reads config file to determine window size
int colNum;
int rowNum;
int mineNum;
std::fstream reader("boards\\config.cfg");
string readString;
if (!reader.is_open())
{
std::cout << "File could not be opened" << std::endl;
return 0;
}
// Reads col #, row #, and mine # in that order
std::getline(reader, readString);
colNum = stoi(readString);
std::getline(reader, readString);
rowNum = stoi(readString);
std::getline(reader, readString);
mineNum = stoi(readString);
reader.close();
// Provided test boards have a size of 25 x 16
sf::RenderWindow window;
window.create(sf::VideoMode((colNum * 32), (rowNum * 32) + 100), "Minesweeper"); // Width, Height
window.setKeyRepeatEnabled(true);
window.setVerticalSyncEnabled(true);
Board testBoard(rowNum, colNum, mineNum);
testBoard.printBoard();
// Tile Testing Code
// Creating sprites for buttons on bottom of game
sf::Sprite testBoardOne;
sf::Sprite testBoardTwo;
sf::Sprite testBoardThree;
sf::Sprite debugButton;
sf::Sprite statusFace;
sf::Sprite timerDigitOne;
sf::Sprite timerDigitTwo;
sf::Sprite timerDigitThree;
// Setting the positions of these sprites
testBoardOne.setPosition(sf::Vector2f(((32 * colNum) - 64), ((32 * rowNum))));
testBoardTwo.setPosition(sf::Vector2f(((32 * colNum) -128), ((32 * rowNum))));
testBoardThree.setPosition(sf::Vector2f(((32 * colNum) - 192), ((32 * rowNum))));
debugButton.setPosition(sf::Vector2f(((32 * colNum) - 256), ((32 * rowNum))));
statusFace.setPosition(sf::Vector2f((((32 * colNum)/2)-32), ((32 * rowNum))));
// Loading the textures onto the sprites
testBoardOne.setTexture(TextureManager::GetTexture("test_1"));
testBoardTwo.setTexture(TextureManager::GetTexture("test_2"));
testBoardThree.setTexture(TextureManager::GetTexture("test_3"));
debugButton.setTexture(TextureManager::GetTexture("debug"));
statusFace.setTexture(TextureManager::GetTexture("face_happy"));
// 2D vector of tiles
std::vector<std::vector<Tile*>> tiles;
//Holding variables for creating Tile objects
Tile* holdingTile;
sf::Sprite* holdingSprite;
for (int i = 0; i < 25; i += 1)
{
std::vector<Tile*> holdingVec;
tiles.push_back(holdingVec);
for (int j = 0; j < 16; j += 1)
{
holdingTile = new Tile(0, i, j);
holdingSprite = new sf::Sprite();
holdingSprite->setTexture(TextureManager::GetTexture("tile_hidden"));
holdingSprite->setPosition(sf::Vector2f((32 * i), (32 * j)));
holdingTile->setBackgroundSprite(holdingSprite);
holdingSprite = new sf::Sprite();
//holdingSprite->setTexture(TextureManager::GetTexture("tile_foreground"));
holdingSprite->setPosition(sf::Vector2f((32 * i), (32 * j)));
holdingTile->setForegroundSprite(holdingSprite);
tiles.at(i).push_back(holdingTile);
}
}
//============================ GAME LOOP ======================================
// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
// Clears previous frame, draws new frame, and displays it
window.clear();
// Draws tiles on board
for (unsigned int i = 0; i < tiles.size(); i += 1)
{
for (unsigned int j = 0; j < tiles.at(i).size(); j += 1)
{
window.draw(*(tiles.at(i).at(j)->getBackgroundSprite()));
window.draw(*(tiles.at(i).at(j)->getForegroundSprite()));
}
}
//Draws "Constant" Buttons, such as debug mode and boards
window.draw(testBoardOne);
window.draw(testBoardTwo);
window.draw(testBoardThree);
window.draw(debugButton);
window.draw(statusFace);
window.display();
// Clicking handlers
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
// transform the mouse position from window coordinates to world coordinates
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
// retrieve the bounding box of the sprite
sf::FloatRect bounds;
for (unsigned int i = 0; i < tiles.size(); i += 1)
{
for (unsigned int j = 0; j < tiles.at(i).size(); j += 1)
{
bounds = tiles.at(i).at(j)->getBackgroundSprite()->getGlobalBounds();
if (bounds.contains(mouse))
{
//std::cout << "Sprite pressed" << std::endl;
tiles.at(i).at(j)->getBackgroundSprite()->setTexture(TextureManager::GetTexture("tile_revealed"));
}
}
}
}
//if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) // WIP - Rapid oscillation of textures
if (sf::Mouse::isButtonPressed(sf::Mouse::Right) && event.type == sf::Event::MouseButtonReleased)
{
// transform the mouse position from window coordinates to world coordinates
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
// retrieve the bounding box of the sprite
sf::FloatRect bounds;
for (unsigned int i = 0; i < tiles.size(); i += 1)
{
for (unsigned int j = 0; j < tiles.at(i).size(); j += 1)
{
bounds = tiles.at(i).at(j)->getBackgroundSprite()->getGlobalBounds();
if (bounds.contains(mouse))
{
std::cout << "Tile right clicked" << std::endl;
if (tiles.at(i).at(j)->isFlagged)
{
tiles.at(i).at(j)->unflagTile();
tiles.at(i).at(j)->getForegroundSprite()->setTexture(TextureManager::GetTexture("tile_foreground"));
}
else
{
tiles.at(i).at(j)->flagTile();
tiles.at(i).at(j)->getForegroundSprite()->setTexture(TextureManager::GetTexture("flag"));
}
}
}
}
}
}
// Make sure to clear the textures at the end of the program to avoid errors
TextureManager::Clear();
return 0;
}
The problem is that you use the sf::Event event variable outside the while (window.pollEvent(event)) loop, so when you use the event, the last event type is assigned to it, which does not necessarily have to be MouseButtonReleased but can be one of these:
https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1Event.php#af41fa9ed45c02449030699f671331d4a
Solution:
Move this condition:
if (sf::Mouse::isButtonPressed(sf::Mouse::Right) && event.type == sf::Event::MouseButtonReleased)
to the while (window.pollEvent(event)) loop and change it to:
if (event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Right)

Position not getting updated in events c++

I want the variable curr_pos_x and curr_pos_y to hold the updated values of the player but whenever i press any up/down/left/down key the second time the position is set to reset and then updated according to the button clicked.
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
if (event.type == sf::Event::KeyPressed)
{
float curr_pos_x;
float curr_pos_y;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
// move right...
curr_pos_x = PLAYER_START_X + PLAYER_WIDTH;
curr_pos_y = PLAYER_START_Y;
player.setPosition(sf::Vector2f(curr_pos_x, curr_pos_y));
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
curr_pos_x = PLAYER_START_X - PLAYER_WIDTH;
curr_pos_y = PLAYER_START_Y;
player.setPosition(sf::Vector2f(curr_pos_x, curr_pos_y));
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
curr_pos_x = PLAYER_START_X;
curr_pos_y = PLAYER_START_Y - PLAYER_HEIGHT;
player.setPosition(sf::Vector2f(curr_pos_x, curr_pos_y));
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
curr_pos_x = PLAYER_START_X;
curr_pos_y = PLAYER_START_Y + PLAYER_HEIGHT;
player.setPosition(sf::Vector2f(curr_pos_x, curr_pos_y));
}
}
}
window.clear(sf::Color::Black);
window.draw(player);
window.display();
}

I don't see the animation of the sprite

This is code after includes:
Sprite player;
Texture playerTexture;
IntRect playerContainer(0, 0, 32, 32);
Vector2f playerPosition;
int playerDirection = 0; // 0 - fwd, 1 - back, 2 - stay
This is animation update method:
void updateAnims(Clock clock, float time) {
if(time > 0.3f) {
if(playerDirection == 0) playerContainer.top = 0;
else if(playerDirection == 1) playerContainer.top = 32;
else if(playerDirection == 2) playerContainer.top = 64;
if(playerContainer.left == 96) playerContainer.left = 0;
else playerContainer.left += 32;
player.setTextureRect(playerContainer);
clock.restart();
}
}
and this method is updated in "int main()" method.
int main() {
// Init window
RenderWindow window(VideoMode(800, 600), "RPG");
Clock gameClock;
Clock animClock;
float gameTime;
float animTime;
// Setting up the player
playerTexture.loadFromFile("player.png");
player.setTexture(playerTexture);
player.setTextureRect(playerContainer);
player.setScale(Vector2f(3.f, 3.f));
playerPosition.x = 30;
playerPosition.y = 120;
player.setPosition(playerPosition);
while(window.isOpen()) {
Event event;
while(window.pollEvent(event)) {
if(event.type == Event::Closed) {
window.close();
}
}
checkInputs(gameTime);
animTime = animClock.getElapsedTime().asSeconds();
updateAnims(animClock, animTime);
window.clear();
gameTime = gameClock.getElapsedTime().asMilliseconds();
gameClock.restart();
window.display();
}
return 0;
}
Turns out that sprite is created in main method, gets texture and texture shape, gets position, but not drawn. Why?
I think think the problem is in animation method but I tried different variations of solutions.
You should call window.draw(player) method between window.clear() and window.display() to actually draw player sprite on screen.

SFML - pollEvent double run mouseclick

I have main like this :
#include <SFML/Graphics.hpp>
#include <iostream>
#include "okno.h"
using namespace sf;
int main()
{
// Create the main window
RenderWindow app(VideoMode::getDesktopMode(), "Okno" ,Style::Fullscreen);
app.setKeyRepeatEnabled(false);
okno aplikacja(app);
// Start the game loop
while (app.isOpen())
{
// Process events
Event event;
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
while (app.pollEvent(event))
{
// Close window : exit
if (event.type == Event::Closed)
app.close();
if( event.type == Event::KeyPressed && event.key.code == Keyboard::Escape )
app.close();
}
aplikacja.click_przyciski(event);
aplikacja.obsluga_przyciskow();
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
aplikacja.rysuj();
aplikacja.menu=true;
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
//sleep(seconds(5));
// Update the window
//app.display();
}
return EXIT_SUCCESS;
}
And class okno.cpp like this :
#include "okno.h"
#include <iostream>
using namespace std;
int wyswietlanie =0;
okno::okno(RenderWindow &app): window(app)
{
textures[0].loadFromFile("grafika/tlo.png");
textures[1].loadFromFile("grafika/logo.png");
textures[2].loadFromFile("grafika/siatka.png");
textures[3].loadFromFile("grafika/button_start.png");
textures[4].loadFromFile("grafika/button_informacje.png");
textures[5].loadFromFile("grafika/button_wyjscie.png");
textures[6].loadFromFile("grafika/button_cofnij.png");
czcionka.loadFromFile("czcionki/czcionka_1.ttf");
for (int j=0;j<i;j++)
sprites[j].setTexture(textures[j]);
float x,y;
x=window.getView().getSize().x;
y=window.getView().getSize().y;
tekst.setString("Projekt wykonal : \n Wojciech Sorota.");
tekst.setCharacterSize(30);
tekst.setPosition(x/10,y/10);
tekst.setColor(sf::Color::Red);
tekst.setFont(czcionka);
sprites[0].setScale(x/sprites[0].getTextureRect().width,y/sprites[0].getTextureRect().height);
sprites[1].setPosition(x/2 - sprites[1].getTextureRect().width/2,y/2 - sprites[1].getTextureRect().height/2);
sprites[3].setPosition(x/10,y/10);
sprites[2].setScale(x/2/sprites[2].getTextureRect().width,y/2/sprites[2].getTextureRect().height);
sprites[2].setPosition(x/8,y/4);
sprites[4].setPosition( x/10+ sprites[3].getPosition().x + x/ 15,y/10 );
sprites[5].setPosition( x/10 +sprites[4].getPosition().x +x/15,y/10);
sprites[6].setPosition(x/10 + tekst.getPosition().x + tekst.getGlobalBounds().width,y/10);
menu=true;
}
okno::~okno()
{}
void okno::rysuj()
{
this->rysuj_intro();
this->rysuj_menu();
}
void okno::start_gra()
{
}
void okno::click_przyciski(Event &event)
{
if(event.type == Event::MouseButtonReleased && event.mouseButton.button == Mouse::Left)
{
if(click_sprite(sprites[3]))
start_gra();
else if(click_sprite(sprites[5]))
window.close();
else if( click_sprite(sprites[4]))
wyswietl_info(event);
}
}
void okno::wyswietl_info(Event &event)
{
{
while(1)
{
if(sf::Mouse::isButtonPressed(sf::Mouse::Left) && click_sprite(sprites[6]))
{
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
return;
}
window.clear();
window.draw(sprites[0]);
window.draw(sprites[2]);
window.draw(sprites[6]);
window.draw(tekst);
obsluga_przyciskow();
window.display();
}
}}
bool okno::click_sprite(Sprite a)
{
// transform the mouse position from window coordinates to world coordinates
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
// retrieve the bounding box of the sprite
sf::FloatRect bounds = a.getGlobalBounds();
// hit test
if (bounds.contains(mouse))
{
return true;
}
return false;
}
void okno::obluga_cofnij()
{
}
void okno::obsluga_przyciskow()
{
if(mysz_nad_sprite(sprites[3]))
sprites[3].setColor(sf::Color(100,100,100));
else
sprites[3].setColor(sf::Color(255,255,255));
if(mysz_nad_sprite(sprites[4]))
sprites[4].setColor(sf::Color(100,100,100));
else
sprites[4].setColor(sf::Color(255,255,255));
if(mysz_nad_sprite(sprites[5]))
sprites[5].setColor(sf::Color(100,100,100));
else
sprites[5].setColor(sf::Color(255,255,255));
if(mysz_nad_sprite(sprites[6]))
sprites[6].setColor(sf::Color(100,100,100));
else
sprites[6].setColor(sf::Color(255,255,255));
}
bool okno::mysz_nad_sprite(Sprite a)
{
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
if (a.getGlobalBounds().contains(mouse))
return true;
return false;
}
void okno::rysuj_intro()
{
if (wyswietlanie == 0)
{
for ( int n=0;n<=254;n++)
{
window.clear();
sprites[0].setColor(sf::Color(255, 255, 255, n));
sprites[1].setColor(sf::Color(255,255,255,n));
sleep(milliseconds(n/15));
window.draw(sprites[0]);
window.draw(sprites[1]);
window.display();
}
for (int n=254;n>=0;n--)
{
window.clear();
sprites[1].setColor(sf::Color(255, 255, 255, n));
sleep(milliseconds(n/15));
window.draw(sprites[0]);
window.draw(sprites[1]);
window.display();
}
wyswietlanie++;
}
}
void okno::rysuj_menu()
{
window.clear();
if (wyswietlanie==1)
for ( int n=0;n<=254;n++)
{
window.clear();
sprites[2].setColor(sf::Color(255,255,255,n));
window.draw(sprites[0]);
window.draw(sprites[2]);
window.draw(sprites[3]);
window.draw(sprites[4]);
window.draw(sprites[5]);
window.display();
if (n==254)
wyswietlanie++;
window.clear();
}
window.draw(sprites[0]);
window.draw(sprites[2]);
window.draw(sprites[3]);
window.draw(sprites[4]);
window.draw(sprites[5]);
window.display();
}
My question is why after i click on sprites[6] then i go back to loop [ pollEvent ] and then pollEvent return last event , but last event is mouseclick soo then it run script on mouseclick how to protect my function for this ?
SFML Event handling
Events should be handled something like this:
sf::Event event;
while (app.pollEvent(event))
{
// handle each event you want
switch (event.type)
{
case sf::Event::Closed:
closed(event);
Exit();
break;
case sf::Event::KeyPressed:
keyPressed(event);
break;
case sf::Event::KeyReleased:
keyReleased(event);
break;
case sf::Event::MouseButtonPressed:
mouseButtonPressed(event);
break;
case sf::Event::MouseButtonReleased:
mouseButtonReleased(event);
break;
case sf::Event::MouseMoved:
mouseMoved(event);
break;
/* ...many more events exist */
default:
cerr << "unhandle event of type: " << event.type << endl;
break;
}
}
And then, have a function for each event you want to handle.
void mouseMoved(const sf::Event& event)
{
// do something with the mouse event
mRelMousePos.x = event.mouseMove.x - mMousePos.x;
mRelMousePos.y = event.mouseMove.y - mMousePos.y;
mMousePos.x = event.mouseMove.x;
mMousePos.y = event.mouseMove.y;
}
As mentionned by #Hiura, you can't assign an event type to an sf::event and then reuse it in the pollEvent method, to be more precise, it's more the event.mouseButton.button = Mouse::Right; part that is problematic here. This is partly because the sf::Event class stores its event parameters (mouseButton, key, etc.) inside a union and partly because that's not the use intended for the sf::Event class.
Your code
Please code in english, always, you never know when you'll need to share a piece of code. And I'm not saying this because I'm a self-centered english speaking individual, in fact, I'm a french canadian.
Now, let's take a look specifically at the code you provided.
// Process events
Event event;
// these are problematic, you shouldn't do that.
//event.type=Event::JoystickButtonPressed;
//event.mouseButton.button = Mouse::Right;
while (app.pollEvent(event))
{
// using a switch or else if here would lower code repetition
// and useless check.
// Since both cases do the same thing, you could have just merge them.
// Close window : exit
if ((event.type == Event::Closed)
|| (event.type == Event::KeyPressed
&& event.key.code == Keyboard::Escape ))
{
app.close();
}
else if (event.type == Event::MouseButtonReleased
&& event.mouseButton.button == Mouse::Left)
{
// this should really go here
aplikacja.click_button(event); // thanks Google Translation
}
}
// Why? Why do you send the last event from your event loop to that?
//aplikacja.click_przyciski(event);
Some unnecessary tweaks here just for fun:
bool okno::click_sprite(Sprite sprite) // remember, meaningful names
{
// transform the mouse position from window coordinates to world coordinates
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
// see how it's clearer and I just removed 7-8 LOC and the comments
// are now unnecessary here. The if clause was redundant since the contains
// method already returns a bool value.
return sprite.getGlobalBounds().contains(mouse);
}
I'm not going to go through the entire code, but you are close to a working app with SFML. There is some nice tutorials and the SFML source code is quite clear, see the SFML Github repo and the SFML game dev book for more info on how to use each part of SFML.