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

Time:01-08

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?

CodePudding user response:

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();
        }
    }
}
  • Related