Home > OS >  Why does isClick become false when button is not being clicked anymore?
Why does isClick become false when button is not being clicked anymore?

Time:12-06

I am working on a button in SFML. std::cout << isClick prints 1 when my mouse is being clicked, but somehow 0 when I let go. I have not put that in my code.

button.cpp:

bool Button::checkClick(sf::RenderWindow& window) {
    sf::Vector2i mousePos = sf::Mouse::getPosition(window);
    if (mousePos.x > pos.x
        && mousePos.x < pos.x   size.x
        && mousePos.y > pos.y
        && mousePos.y < pos.y   size.y) {
            if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
                button.setFillColor(button_color_click);
                isClick = true;
            } else if (isClick == true) {
                isClick = false;
                return true;
            } else {
                button.setFillColor(button_color_hover);
            }
        } else {
            button.setFillColor(button_color);
        }
    std::cout << isClick;
    return false;
}

button.h:

class Button {
    public:
        sf::Vector2f pos, size;
        sf::RectangleShape button;
        sf::Text text;
        bool isClick = false;

        sf::Color button_color, button_color_hover, button_color_click;

        Button(sf::Vector2f pos_, sf::Vector2f size_, std::string text_, sf::Font& font, float font_size, sf::Color button_color_, sf::Color button_color_hover_, sf::Color button_color_click_, sf::Color text_color, float outline, sf::Color outline_color);
        void draw(sf::RenderWindow& window);
        bool checkClick(sf::RenderWindow& window);
};

How I call it in main.cpp:

if (newGameButton.checkClick(window)) {
    resetGame(window, status, ball, velocity, paddle1, paddle2);
    std::cout << "clicked\n";
}

Except it is not printing anything.

I want isClick to not return false once I let go.

EDIT: Every other line of code that involves button newGameButton and button class:

void drawGameEnded(sf::RenderWindow& window, gameStatus& status, sf::Text& winningText, Button newGameButton, sf::CircleShape& ball, sf::Vector2f& velocity, sf::RectangleShape& paddle1, sf::RectangleShape& paddle2) {
    // change winning text    

    winningText.setString(status.winner ? "Player 1 Wins!" : "Player 2 Wins!");

    // update button

    if (newGameButton.checkClick(window)) {
        resetGame(window, status, ball, velocity, paddle1, paddle2);
        std::cout << "clicked\n";
    }

    // draw everything on screen
    
    window.clear();

    window.draw(winningText);
    newGameButton.draw(window);

    window.display();
}

Main loop:

sf::Clock deltaTime;
gameStatus status;

while (window.isOpen())
{
    sf::Time dt = deltaTime.restart();
    sf::Event event;
    while (window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
            window.close();
    }

    if (!status.gameEnded) {
        drawGame(paddle1, paddle2, ball, velocity, dt, window, paddleSpeed, status);
        continue;
    }
    drawGameEnded(window, status, winningText, newGameButton, ball, velocity, paddle1, paddle2);

}

Initialising newGameButton:

Button newGameButton(sf::Vector2f(400.f, 500.f), sf::Vector2f(400.f, 150.f), "New Game", droid_sans, 24.f, grey1, grey3, grey4, grey2, 10, grey2);

button.cpp (without Button::checkClick()):

#include <SFML/Graphics.hpp>
#include "button.h"
#include <iostream>

Button::Button(sf::Vector2f pos_, sf::Vector2f size_, std::string text_, sf::Font& font, float font_size, sf::Color button_color_, sf::Color button_color_hover_, sf::Color button_color_click_, sf::Color text_color, float outline, sf::Color outline_color) {
    button.setPosition(pos_);
    button.setSize(size_);
    button.setFillColor(button_color_);
    button.setOutlineThickness(outline);
    button.setOutlineColor(outline_color);
    text.setFont(font);
    text.setCharacterSize(font_size);
    text.setString(text_);
    text.setFillColor(text_color);
    text.setPosition(pos_.x (size_.x-text.getGlobalBounds().width)/2, pos_.y (size_.y-text.getGlobalBounds().height)/2);
    pos = pos_;
    size = size_;
    button_color = button_color_;
    button_color_click = button_color_click_;
    button_color_hover = button_color_hover_;
}

void Button::draw(sf::RenderWindow& window) {
    window.draw(button);
    window.draw(text);
}

CodePudding user response:

OK, the problem is that you are copying your button object, and modifying the copy. That's why the isClick variable seems to go back to false.

The copy happens here

void drawGameEnded(sf::RenderWindow& window, gameStatus& status, sf::Text& winningText, 
    Button newGameButton, sf::CircleShape& ball, sf::Vector2f& velocity, 
    sf::RectangleShape& paddle1, sf::RectangleShape& paddle2) {

It should be pass by reference to avoid the copy

void drawGameEnded(sf::RenderWindow& window, gameStatus& status, sf::Text& winningText, 
    Button& newGameButton, sf::CircleShape& ball, sf::Vector2f& velocity, 
    sf::RectangleShape& paddle1, sf::RectangleShape& paddle2) {

CodePudding user response:

In below condition, you are not returning anything from the method:

if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
            button.setFillColor(button_color_click);
            isClick = true;                
        }

As a result, execution continues till the last statement i.e. "return false".

Try adding return statement as below.

if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
            button.setFillColor(button_color_click);
            isClick = true;
            return true;
        }
  • Related