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

Author Topic: Capturing keypresses every frame  (Read 7748 times)

0 Members and 1 Guest are viewing this topic.

Lamonte

  • Newbie
  • *
  • Posts: 46
    • View Profile
Capturing keypresses every frame
« on: September 04, 2013, 09:09:12 pm »
I had issues using the win.keypressed window event handler so I found a post that said if I wanted to capture keypresses every frame I would need to use Keyboard.IsKeypressed() which works wonderfully, except Laurent said in a post I randomly stumbled upon that you shouldn't use this because it executes even if the window isn't focused.

Is there a work around to this?  Because I couldn't previously get the window key events to work how I wanted as it didn't want to capture when the key was being held down, I was forced to press down everytime to do what I wanted.  Which didn't make sense.

Hope I explained everything correctly.  Basically I'm looking for a way to disable the keyboard.iskeypressed when the window isn't focused or if there is a better way to use window keyboard events that captures when you hold down on the key properly because win.SetKeyRepeatEnabled(true); doesn't help the situation.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
AW: Capturing keypresses every frame
« Reply #1 on: September 04, 2013, 09:36:35 pm »
You should simply track the GainedFocus and LostFocus event and only process the keyboard inputs if there's a focus.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Lamonte

  • Newbie
  • *
  • Posts: 46
    • View Profile
Re: Capturing keypresses every frame
« Reply #2 on: September 04, 2013, 10:26:06 pm »
Thanks, works nicely.

            //check window focus
            win.GainedFocus += (s, e) => focused = true;
            win.LostFocus   += (s, e) => focused = false;

Lamonte

  • Newbie
  • *
  • Posts: 46
    • View Profile
Re: Capturing keypresses every frame
« Reply #3 on: September 04, 2013, 10:36:26 pm »
Actually this is weird as hell.  When you load the application the window should automatically gain a focus state, but it doesn't.  So you have to focus, unfocus and refocus before it actually checks the event? uh?


                bool focused = true; //could be set to false as well
       
            //setup window
            RenderWindow win = new RenderWindow(new VideoMode((uint) width, (uint) height), title);
           
            //check window focus
            win.GainedFocus += (s, e) => focused = true;
            win.LostFocus   += (s, e) => focused = false;

            //setup frames
            win.SetFramerateLimit(60);

            while (win.IsOpen())
            {
                win.DispatchEvents();

                //... <snipped> ...//
            }

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Capturing keypresses every frame
« Reply #4 on: September 04, 2013, 10:47:03 pm »
A workaround to a workaround is often worse. Let's rather solve the initial problem:

Quote
I had issues using the win.keypressed window event handler

... which issues?
Laurent Gomila - SFML developer

Lamonte

  • Newbie
  • *
  • Posts: 46
    • View Profile
Re: Capturing keypresses every frame
« Reply #5 on: September 04, 2013, 11:09:11 pm »
A workaround to a workaround is often worse. Let's rather solve the initial problem:

Quote
I had issues using the win.keypressed window event handler

... which issues?

My keypresses didn't trigger every frame when holding the key down, even with the set key repeat option set to true.  Making wasd movement silly as mentioned in the op.

G.

  • Hero Member
  • *****
  • Posts: 1592
    • View Profile
Re: Capturing keypresses every frame
« Reply #6 on: September 05, 2013, 12:12:47 am »
Was you code inside the event checking loop?

Lamonte

  • Newbie
  • *
  • Posts: 46
    • View Profile
Re: Capturing keypresses every frame
« Reply #7 on: September 05, 2013, 12:56:55 am »
Was you code inside the event checking loop?

My current code passes a function to the window loop which checks the movement of the player eg.:

                        if(Keyboard.IsKeyPressed(Keyboard.Key.W)) {
                                y -= speed;
                        }

                        if(Keyboard.IsKeyPressed(Keyboard.Key.S)) {
                                y += speed;
                        }

You kind of get the point, well it was similar except it used the window.KeyPressed += EventHandler<KeyEventArgs>(myfunctionhere);

And the code was similar, don't have the original code anymore
if(e.Code == Keyboard.Key.W) {
        ...
}

Difference is the code wasn't much different in body, but the way it interacted was completed different.  I could hold down WASD and it would stay going in the direction I wanted my sprite to go until I let go of the key.  Using the event handler thing only executed once until i let go and pressed it again.  So basically spamming the button to move the sprite anywhere.  Like I said in previous posts, I had win.SetKeyRepeatEnabled(true); set and it gave the same effect.  It just didn't work as I intended it to.  I needed my sprite to move by frame, funny how much different the C# binding is from C++

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Capturing keypresses every frame
« Reply #8 on: September 05, 2013, 03:20:20 am »
Was you code inside the event checking loop?

In the .NET bindings there is no "event loop" like your used to in plain C++ SFML.

Difference is the code wasn't much different in body, but the way it interacted was completed different.  I could hold down WASD and it would stay going in the direction I wanted my sprite to go until I let go of the key.  Using the event handler thing only executed once until i let go and pressed it again.  So basically spamming the button to move the sprite anywhere.  Like I said in previous posts, I had win.SetKeyRepeatEnabled(true); set and it gave the same effect.  It just didn't work as I intended it to.  I needed my sprite to move by frame, funny how much different the C# binding is from C++

You are way over complicating something simple. Handle the key pressed and key released events like you were. Disable the key repeating (RenderWindow.SetKeyRepeatEnabled(false) and add a boolean flag to your class to determine if a key is pressed or not. Do something like this (not written in IDE - don't copy paste)...

class KeyPressExample
{
   private bool _uppressed = false;
   private void KeyPressed(object sender, KeyEventArgs e)
   {
       if (e.Key == Key.W)
      {
         _uppressed = true;
      }
   }
   private void KeyReleased(object sender, KeyEventArgs e)
   {
       if (e.Key == Key.W)
      {
         _uppressed = false;
      }
   }
   public void GameLoop()
   {
      win.DispatchEvents();
      if (_uppressed)
      {
         //Move Sprite
         //Remember delta time
      }
      win.Clear();
      //Draw Sprite
      win.Display();
   }
}
 

By the way this is the "correct" way to do this. Even in the C++ examples of the SFML Game Development book there is a boolean flag that is set from the C++ event loop to determine if the player is to move or not.
« Last Edit: September 05, 2013, 03:22:16 am by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Lamonte

  • Newbie
  • *
  • Posts: 46
    • View Profile
Re: Capturing keypresses every frame
« Reply #9 on: September 05, 2013, 04:22:36 am »
Alright that worked, I guess my last question would now be why does the SFML window not refocus when you click inside the window, but only when clicking the window bar?

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Capturing keypresses every frame
« Reply #10 on: September 05, 2013, 04:38:52 am »
Alright that worked, I guess my last question would now be why does the SFML window not refocus when you click inside the window, but only when clicking the window bar?

This is a bug that was unintentionally introduced in SFML 2.1 as a fix to another bug.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Lamonte

  • Newbie
  • *
  • Posts: 46
    • View Profile
Re: Capturing keypresses every frame
« Reply #11 on: September 05, 2013, 04:51:02 am »
Alright that worked, I guess my last question would now be why does the SFML window not refocus when you click inside the window, but only when clicking the window bar?

This is a bug that was unintentionally introduced in SFML 2.1 as a fix to another bug.

Ah okay, thanks for the info.  Is there a place I can find a list of bugs for the current version?

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Capturing keypresses every frame
« Reply #12 on: September 05, 2013, 07:12:21 am »
https://github.com/SFML/SFML/issues?milestone=8&state=open is probably the closest there is to an official bug list

The bug you were asking about is issue #437.