Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Keyboard events are getting checked twice before a call to clear and display.  (Read 1001 times)

0 Members and 1 Guest are viewing this topic.

billy.spiva

  • Newbie
  • *
  • Posts: 5
    • View Profile
Okay,  I'm getting really stuttering animations using a sprite sheet.

This is in main where I call my functions to check the keyboard events, and then display everything.

else
        {
            Keyboard_Control(window,Run,event,NewGame,Pause,text,Player1,clock);
            Display_Main(window,Player1);
        }
 

Here is my functions to animate and display the sprite.

void Entity::Display_Self(sf::RenderWindow& window)
{
    sprite.setPosition(sf::Vector2f(X,Y));
    window.draw(sprite);
    std::cout<<"XR displayed is "<<std::to_string(XR)<<std::endl;
}

void Entity::Animate_Self(bool& Next)
{
    if(MR==true)
    {
        if(Next==true)
        {
            XR+=64;
            if(XR>256)
            {
                XR=64;
            }
        }
    }
    else if(Id==true)
    {
        XR=0;
    }
    sprite.setTextureRect(sf::IntRect(XR,YR,64,64));
    std::cout<<"XR animated is "<<std::to_string(XR)<<std::endl;
}
 

The Display_Self is called in Display_Main, and the Animate_Self is called under the Keyboard_Control.

I used the couts in each to generate some data to show me what was happening, so, I'll post that too.

XR displayed is 128
XR displayed is 128
XR displayed is 128
XR displayed is 128
XR displayed is 128
XR animated is 192
XR animated is 256
XR displayed is 256
XR displayed is 256
XR displayed is 256
XR displayed is 256
XR displayed is 256
XR animated is 64
XR animated is 128
XR displayed is 128
XR displayed is 128
XR displayed is 128
XR displayed is 128
XR displayed is 128
XR displayed is 128
XR animated is 192
XR animated is 256
XR displayed is 256
XR displayed is 256
XR displayed is 256
XR displayed is 256
XR displayed is 256
 

The problem, to me, appears to be that the keyboard events are getting checked twice, without a call to display being made, followed by several calls to display with no keyboard event checks in between.  The functions are supposed to be called one right after the other, and I don't know what is going on here!

Let me know if you need any more information.  Thanks.
« Last Edit: January 26, 2024, 07:48:24 pm by billy.spiva »

billy.spiva

  • Newbie
  • *
  • Posts: 5
    • View Profile
Update:

After doing a little more work on the code, The event loop is processing two events while the key is held down in one loop of the main while statement before the Display_Main function is called.

Is there a way, using pollEvents, to get it to only process one event each loop?

I'm going to try using the break keyword in the event loop, see if that helps.

billy.spiva

  • Newbie
  • *
  • Posts: 5
    • View Profile
Adding the break keyword worked!

while(window.pollEvent(event))
    {
        if(event.type==sf::Event::Closed)
        {
            Run=false;
        }
        else if((event.type==sf::Event::KeyPressed)&&(event.key.code==sf::Keyboard::Escape))
        {
            Run=false;
        }
        else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
        {
            Player1.MR=true;
            Player1.Id=false;
            if (NZ>0.1f)//was 0.05f
            {
                Next=true;
                Player1.Animate_Self(Next);
                clock.restart();
            }
            break;
        }
        else if((event.type==sf::Event::KeyReleased)&&(event.key.code==sf::Keyboard::D))
        {
            Player1.MR=false;
            Player1.Id=true;
            Player1.Animate_Self(Next);
            clock.restart();
        }
    }

 

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
SFML has two ways of doing keyboard input:
- event based using pollEvent and checking for sf::Event::KeyPressed and sf::Event::KeyReleased
- immediate check using sf::Keyboard::isKeyPressed.

Generally you shouldn't use isKeyPressed inside of the event loop (or really do almost any of the main game logic). This is because isKeyPressed is usually used when you want to check if a key is currently held down, but the event loop only runs when a key starts to be pressed or gets released, not in between.
(The event loop will also pick up key repeat events when the OS starts doing them, so it will happen more than just twice, but not at the frame rate)