简体   繁体   English

ButtonTestSFML - 单击按钮 state

[英]ButtonTestSFML - Button clicked state

I have a minor problem in my code and can't resolve it.我的代码中有一个小问题,无法解决。 I created a Button class using SFML library.我使用 SFML 库创建了一个按钮 class。 Its just code practice since I'm relatively new to programing.它只是代码练习,因为我对编程还比较陌生。

But the problem is that I can't make it work on release, it only works when pressed.但问题是我不能让它在发布时工作,它只能在按下时工作。 So instead of one click it registers multiple clicks while it is being pressed.因此,它不是单击一次,而是在按下时记录多次单击。 It's best to try the given code to see what I mean.最好尝试给定的代码以了解我的意思。

Thanks in advance!提前致谢!

Here is code for Button class:这是按钮 class 的代码:

    class Button
{
    private:
    
        //Button Text Params:
        sf::Font font;                  
        sf::Text text;                  
        sf::Vector2f textPos;           
        sf::Vector2f textBounds;        
        //Button Shape Params:
        sf::RectangleShape shape;
        sf::Vector2f pos;               
        sf::Vector2f size;              
        //Button colors(Hover and Default)
        sf::Color DefaultColor;         
        sf::Color hColor;     
        //Button Sounds:
        sf::SoundBuffer bf1;            
        sf::SoundBuffer bf2;            
        sf::Sound HoverSound;           
        sf::Sound ClickSound;           

        bool wFocus = false;            //Returns focus on main window
        
        bool ButtonClick = false;       //Controls the code on button click
        
        bool CursorOverButton(sf::RenderWindow &window) //Detect cursor pos on window
        {
            sf::Vector2f CursorPos = (sf::Vector2f)sf::Mouse::getPosition(window);

            if((CursorPos.x < (pos.x + size.x) && CursorPos.x > pos.x) && (CursorPos.y < (pos.y + size.y) && CursorPos.y > pos.y))
            {

                if(shape.getFillColor() != hColor){     //if cursor passes over window 
                    shape.setFillColor(hColor);         //all of this will execute
                    HoverSound.play();
                }
                return true;
            }
            else 
            {
                shape.setFillColor(DefaultColor);
                return false;
            }
        }

    public:

        Button()
        {
            font.loadFromFile("arial.ttf"); //Loads font for Button text default is ariel(change to what you want!)
        }
        //Button Creation:
        void create(std::string ButtonText, int TextSize,  sf::Color Color, float buttonWidth, float buttonHeight, float x, float y, sf::Color HoverColor)
        {
            //Create Button size and position:
            pos.x = x;
            pos.y = y;
            size.x = buttonWidth;
            size.y = buttonHeight;
            DefaultColor = Color;
            hColor = HoverColor;
            
            //Load text for button:
            text.setFont(font);
            text.setCharacterSize(TextSize);
            text.setString(ButtonText);
            text.setOutlineColor(sf::Color::Black);
            text.setOutlineThickness(2);
            sf::FloatRect fr =  text.getGlobalBounds();
            textBounds.x = fr.width + fr.left;
            textBounds.y = fr.height + fr.top;
            
            //Apply parameters to shape:
            shape.setSize(size);
            shape.setFillColor(DefaultColor);
            shape.setPosition(pos);
            
            //Fit text to button:
            text.setOrigin(textBounds.x/2, textBounds.y/2);
            text.setPosition(pos.x + (size.x/2), pos.y + (size.y/2) - 1);
        }
        
        
        bool isButtonClicked(sf::RenderWindow &window) //When button is pressed down whis executes
        {
            if(!CursorOverButton(window)) //Tests focus on window
            {
                wFocus = (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))? true : false;
            }
            if(CursorOverButton(window) && !wFocus && sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
            {
                if(!ButtonClick) ClickSound.play(); //Plays only on first click
                ButtonClick = true;
                return true;
            }
            else ButtonClick = false; //Return clicked state
            return false;
        }

        void HoverClickSound(std::string HoverSoundPath1, std::string ClickSoundPath2) //add sounds to buffer and load into
        {                                                                              //playable sound
            bf1.loadFromFile(HoverSoundPath1);
            HoverSound.setBuffer(bf1);
            bf2.loadFromFile(ClickSoundPath2);
            ClickSound.setBuffer(bf2);
        }
        
        void draw(sf::RenderWindow &window) //draws button on window(with text)
        {
            window.draw(shape);
            if(textBounds.x < size.x || textBounds.y < size.y) window.draw(text);
        }
};

Full Code with test is here on github带有测试的完整代码在 github 上

So I came across a solution(for the most part) it still registers on being pressed but registers only the first initial press down, once, and doesn't execute the wanted code more then once.所以我遇到了一个解决方案(大部分情况下)它仍然在被按下时注册,但只注册第一次初始按下,一次,并且不会多次执行所需的代码。 Say you want to increment a value by one when button is clicked it used to run the code while button is pressed multiple times(because of the refresh rate), now this part of code wont let it continue after initial press down:假设您想在单击按钮时将值加一,它曾经在多次按下按钮时运行代码(由于刷新率),现在这部分代码不会让它在初始按下后继续:

bool isButtonClicked(sf::RenderWindow &window) //When button is pressed down whis executes
        {
            if(!CursorOverButton(window)) //Tests focus on window
            {
                wFocus = (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))? true : false;
            }
            if(CursorOverButton(window) && !wFocus && sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
            {
                if(!ButtonClick)  //This wont let it execute more then once on click
                { 
                    ClickSound.play();
                    ButtonClick = true;
                    return true;
                }
                else return false;
            }
            else ButtonClick = false; //Return clicked state
            return false;
        }

Thoughts?想法?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM