0

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?

genpfault
  • 51,148
  • 11
  • 85
  • 139
czakub
  • 5
  • 5
  • 1
    [using namespace std](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) is considered bad practice. – aqua959 Jan 06 '23 at 17:59
  • Oh, I didn't knew that, why is it considered a bad practice? – czakub Jan 06 '23 at 19:09
  • `#include` is another bad practice. [https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – drescherjm Jan 06 '23 at 19:17
  • I see, thanks, I will change that. But can somone help me with this button, I'm still clueless – czakub Jan 06 '23 at 19:56

1 Answers1

0

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();
        }
    }
}
aqua959
  • 99
  • 1
  • 14
  • This don't work – czakub Jan 07 '23 at 13:51
  • What do you mean this doesn't work? Have you changed the color of your button fill color? – aqua959 Jan 07 '23 at 17:42
  • I'm sorry, I tried today and it worked I must missed something, sorry. One more question, is there any way to make this button dont blink when mouse is over it? – czakub Jan 08 '23 at 11:14
  • I fixed this, I had two window.display() commands – czakub Jan 08 '23 at 16:49
  • I'm confused. Isn't having the color change when the mouse hovers over it what you want to do, as suggested by "why it don't fill color when my mouse is at the button"? – aqua959 Jan 09 '23 at 06:20
  • 1
    Also, these types of problems are nicely solved by debuggers and print statements. Learn the common debugging techniques so you won't have these kind of problems later! – aqua959 Jan 09 '23 at 06:21