SFML community forums

Help => General => Topic started by: MarbleXeno on August 07, 2020, 10:48:20 pm

Title: [solved] Dumb and simple question about input.
Post by: MarbleXeno on August 07, 2020, 10:48:20 pm
I want the texture to change to a muted speaker when the player click on the speaker, and after one more click I want the texture to change to the speaker that is on, my problem is that since im doing this in update and since that im also using isButtonPressed the texture is changing instantly every frame, so when i click really fast, it works good, but when i click normally the texture is instantly looping, like changing every frame, so quick. I want to do a normal switch that mutes the audio on click, and when audio is muted, after another click, i want the texture to change to normal again and play the music, i know how to mess with sound and animations but i dont know how to make this simple input thing.

So how to make a simple one input, like:
One click, change the frame but only once.
Another click, change the frame again.

Since my main lang isnt eng and my speaking skills arent as good as i want, i just recorded this vid of the problem:
https://www.youtube.com/watch?v=i7CqAe4QJ2Q&feature=youtu.be

the code:
                //speaker
                if (engine.checkMouseCollision(*pointer_window, speaker_sprite.getGlobalBounds()) == true) {

                        if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) && isSpeakerMuted == false) {
                                speaker_sprite.setTextureRect({ 60, 3, 47, 44 });
                                isSpeakerMuted = true;
                        }
                        else if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left) && isSpeakerMuted == true) {
                                speaker_sprite.setTextureRect({ 3, 3, 46, 44 });
                                isSpeakerMuted = false;
                        }
                        speaker_sprite.setColor(sf::Color::Magenta);
                }
                else {
                        speaker_sprite.setColor(sf::Color::White);
                }

        }
Title: Re: Dumb and simple question about input.
Post by: G. on August 08, 2020, 05:51:25 am
You can use the MouseButtonPressed event (https://www.sfml-dev.org/tutorials/2.5/window-events.php), it is triggered only once when you click.
Title: Re: Dumb and simple question about input.
Post by: MarbleXeno on August 08, 2020, 11:55:00 am
Ok but how can i use events outside the main method? For example in a Menu Class.
Title: Re: Dumb and simple question about input.
Post by: Paul on August 08, 2020, 03:31:52 pm
Put your menu update method into process events.

        sf::Event event;
        while (window.pollEvent(event))
        {
                switch (event.type)
                {
                case sf::Event::MouseButtonPressed:
                        MyMenuClass.OnMouseClick(event.mouseButton.button);
                        break;
                }
        }
Title: Re: Dumb and simple question about input.
Post by: MarbleXeno on August 08, 2020, 04:31:25 pm
hmm, i dont understand exactly what do you mean, could you explain more? What should the "OnMouseClick" function look like?

Sorry, im still learning sfml.
Title: Re: Dumb and simple question about input.
Post by: Paul on August 08, 2020, 08:10:08 pm
It should be similar to your code above - check mouse cursor collision vs menu objects and then execute an action.

You will have something like MyMenuClass.OnUpdate(), which runs constantly in main loop and where you will change graphics depending on whether mouse cursor is over objects. And second method MyMenuClass.OnMouseClick() in events, which is performed only if you press the mouse button. It prevents constant switching.

In some improved system you can also add events like OnMouseEnter(), OnMouseLeave() or whatever, but it is not essential. These things with UI aren't entirely simple.
Title: Re: Dumb and simple question about input.
Post by: MarbleXeno on August 08, 2020, 09:18:51 pm
Ok, so now i understand, i'll try implement that, if I have a problem in some time, I will write in this thread. Thanks for the help!

Oh, and last question, what should the parameter look in OnMouseClick? I mean, beacouse later, in this onClickMouse function i need to check if its a left button, so how this should look?
I see:
MyMenuClass.OnMouseClick(event.mouseButton.button);
, so the parameter will be just sf::Event evnt?
Title: Re: Dumb and simple question about input.
Post by: Paul on August 08, 2020, 09:55:00 pm
You will probably use only left mouse button, then:
        //In process events
        sf::Event event;
        while (window.pollEvent(event))
        {
                switch (event.type)
                {
                case sf::Event::MouseButtonPressed:
                        if (event.mouseButton.button == sf::Mouse::Left)
                        {
                                MyMenuClass.OnMouseClick();
                        }
                        break;
                }
        }
 

Otherwise:
//Class
void MyMenuClass::OnMouseClick(const sf::Mouse::Button& button)
{
        if (button == sf::Mouse::Left)
        {
                // Do something..
        }

        if (button == sf::Mouse::Right)
        {
                // Do something..
        }
}

..
// In process events
case sf::Event::MouseButtonPressed:
        MyMenuClass.OnMouseClick(event.mouseButton.button);                    
        break;         
 

Documentation is done very well, check tutorials https://www.sfml-dev.org/tutorials/2.5/window-events.php
Title: Re: Dumb and simple question about input.
Post by: MarbleXeno on August 09, 2020, 12:28:09 am
Okay, thank you for the help and for your patience.
Title: Re: Dumb and simple question about input.
Post by: MarbleXeno on August 09, 2020, 12:27:11 pm
Okay, I fixed it, it was SO EASY. I'm just stupid sometimes and even the easiest things aren't that easy for me when it''s happening.