Search code examples
c++sfml

SFML mouse button released is spamming


I am using SFML and C++ and I am getting an odd problem,

Here is my main game update method

while (renderService.Window.isOpen())
{
    //Poll events
    sf::Event event;
    while (renderService.Window.pollEvent(event))
    {
        if (event.type == sf::Event::Closed)
            renderService.Window.close();
        running = false;
    }

    MouseMovment(event);
    MouseClick(event);
    Update();
    Draw();
}

and here is my MouseClick method

void Game::MouseClick(sf::Event event)
{
sf::Vector2i position = sf::Mouse::getPosition(renderService.Window);

    if (event.mouseButton.button == sf::Mouse::Left && event.type == sf::Event::MouseButtonReleased)
    {
        std::cout << "Mouse released" << std::endl;
    }
}

now here is the weird part, in my console sometimes my cout will be spammed like 10/20 times, but sometimes it will work perfectly, am I calling the event wrongly?


Solution

  • You're doing it wrong, suppose that a MouseButtonReleased event is fired and your polling function grabs it (follows the numbers in the comments):

    while (renderService.Window.isOpen()) // 4) The loop starts again
    {
        //Poll events
        sf::Event event; 
        while (renderService.Window.pollEvent(event)) // 1) Grabs the event // 5) No more events
        {
            if (event.type == sf::Event::Closed) // 2) Nope, it's not this one
                renderService.Window.close();
            running = false;
        }
    
        MouseMovment(event);
        MouseClick(event); // 3) Yes, handle it // 6) Uses the unmodified event variable - undefined behavior
        Update();
        Draw();
    }
    

    you should rather do something like:

    sf::Event event;
    
    // while there are pending events...
    while (window.pollEvent(event))
    {
        // check the type of the event...
        switch (event.type)
        {
            // window closed
            case sf::Event::Closed:
                ...
                break;
    
            // mouse button released
            case sf::Event::MouseButtonReleased:
            {
               if (event.mouseButton.button == sf::Mouse::Left)
                ...
            } break;
    
            // we don't process other types of events
            default:
                break;
        }
    
    }