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

Author Topic: [Solved] How to adjust the delays involved in KeyRepeat?  (Read 6364 times)

0 Members and 1 Guest are viewing this topic.

vlad

  • Newbie
  • *
  • Posts: 9
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« on: July 13, 2011, 09:50:58 pm »
Hi,

I assure you I've done some research on the subject in the documentation and this forum, but I still can't figure out how to adjust these two delays:

- the time you have to keep a key pressed for the system to understand that you want to repeat the input
- the time between two key repetitions

Does anyone have a clue?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #1 on: July 13, 2011, 09:54:03 pm »
SFML uses the OS settings, you can't change them in your program.
Laurent Gomila - SFML developer

vlad

  • Newbie
  • *
  • Posts: 9
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #2 on: July 14, 2011, 05:34:13 pm »
Got it.

I'll try to find a way to make my character move smoothly then I'll post the solution in this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #3 on: July 14, 2011, 05:43:15 pm »
The solution is sf::Input (look at the tutorials).
Laurent Gomila - SFML developer

vlad

  • Newbie
  • *
  • Posts: 9
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #4 on: July 14, 2011, 08:18:24 pm »
I've looked pretty much everywhere sf::Input was mentioned, and still can't find a way to adjust these settings without using the clock. Do you have a more specific clue concerning the location of the solution?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #5 on: July 14, 2011, 08:48:00 pm »
sf::Input is not for adjusting these settings, but rather to help you to implement smooth character movement.
Laurent Gomila - SFML developer

vlad

  • Newbie
  • *
  • Posts: 9
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #6 on: July 14, 2011, 10:20:45 pm »
I think I'll just go with SDL for event handling, or just recode my main loop so it checks the keyboard's state every 60 frames.

Laurent > Does the next version of SFML include the possibility to modify these delays?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #7 on: July 14, 2011, 10:26:27 pm »
You should not stick to a manual modification of the repeat times just because you did this in SDL. Smooth character movement can certainly be implemented by using sf::Input, so what doesn't work exactly? Or why do you think you need sf::Event for that?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #8 on: July 15, 2011, 01:00:32 am »
Maybe you're using SFML 2.0 and that's why you're having trouble understanding what's sf::Input. Read the following doc, it should help you:
http://www.sfml-dev.org/documentation/2.0/classsf_1_1Keyboard.php#details

If you're using SFML 1.6 read the "Getting real-time inputs" section here:
http://www.sfml-dev.org/tutorials/1.6/window-events.php

vlad

  • Newbie
  • *
  • Posts: 9
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #9 on: July 15, 2011, 06:50:45 pm »
Contadotempo > I'm using SFML 1.6, I should have mentioned it in the first post.
I assure you I understand pretty well how sf::Input works and I've read the doc. The solution I expected simply isn't available in SFML. I started 2D programming with SDL, that's why I was hoping for an SDL-ish solution.

Nexus > As it turned out I didn't go with SDL for event handling, I just modified my main loop:

Old loop:
Code: [Select]
while(app.IsOpened())
{
Event event;
while(app.GetEvent(event))
{
if(event.Type == Event::Closed)
app.Close();
if(event.Type == Event::KeyPressed || event.Type == Event::KeyReleased)
{
// this function moves a character on the screen toward
// a certain direction given which keys are pressed
GameInput::readInput(&(app.GetInput()), &hero);
}
}
app.Clear();
hero.draw(app);
app.Display();
}


New loop:
Code: [Select]
while(app.IsOpened())
{
// clk is the loop's clock
clk.Reset();
Event event;
while(app.GetEvent(event))
{
if(event.Type == Event::Closed)
app.Close();
}
// this time, the main function is called at each iteration of the loop
// regardless of whether a key's been pressed
GameInput::readInput(&(app.GetInput()), &hero);
app.Clear();
hero.draw(app);
app.Display();
// this line ensures that one iteration takes no less than 60 ms.
while(clk.GetElapsedTime() < 0.060);
}


The problem with the old loop was that my character moved oddly, since the KeyRepeat parameters depend on the OS settings: each time I ordered him to move, he would make a first step, pause for a second, then resume walking at a reasonable pace. Exactly what happens when you hold a key while editing a text file.

I didn't like this behavior but liked even less the idea of having to change the Windows settings to make him walk smoothly.

The optimal solution would have been to modify the first delay involved in the KeyRepeat process, like it's possible in SDL. But as I said enough times, this feature isn't available in SFML, as Laurent confirmed in the second post:
Quote
SFML uses the OS settings, you can't change them in your program.


So instead I wrote a new loop which involves a solution where the key states are checked at each iteration of the main loop, whether a key's been pressed or not.
A loop at the end of the main one ensures the refreshing rate is no less than 60 ms.

It works pretty fine, but I consider this to be too much DIY for my taste and it seems to make the processor work harder.

A fine way to improve this solution would be to replace the last loop:
Code: [Select]
while(clk.GetElapsedTime() < 0.060); With something along the lines of
Code: [Select]
SleepUntil(clk.GetElapsedTime() < 0.060);

I'll check in the documentation if there a sleep() function, but it doesn't seem so. Perhaps by using threads?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #10 on: July 15, 2011, 07:50:52 pm »
Quote from: "vlad"
A loop at the end of the main one ensures the refreshing rate is no less than 60 ms.
An alternative is to pass the frame time to your function and to move the player accordingly.

Quote from: "vlad"
I'll check in the documentation if there a sleep() function, but it doesn't seem so. Perhaps by using threads?
There is, but only in the new documentation. It has already existed in SFML 1.6, though (where it takes seconds, not milliseconds). But you can also use sf::Window::SetFramerateLimit() if you need a constant frame rate.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

vlad

  • Newbie
  • *
  • Posts: 9
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #11 on: July 15, 2011, 09:38:51 pm »
Got it for sf::Sleep().

Quote from: "Nexus"
Quote from: "vlad"
A loop at the end of the main one ensures the refreshing rate is no less than 60 ms.
An alternative is to pass the frame time to your function and to move the player accordingly.
Sorry, but I don't get what you mean by "pass the frame time to [my] function" (which function?)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #12 on: July 15, 2011, 10:30:35 pm »
To readInput(). Okay, the function name is not ideal if readInput() also affects the game entities.

Often, game entities like players/enemies/heroes/projectiles have an update/tick/step/think/... function which is called every frame. You could also do that in the Game class, if the object itself doesn't have complex responsibilities:
Code: [Select]
void Game::readInput(float dt, Hero* hero)
{
    sf::Vector2f velocity = /* compute normalized vector from sf::Input */
    hero->Move(dt * velocity);
}

So, the game logic depends on the time passed each frame (you could pass sf::Window::GetFrameTime() as first argument). But sometimes it is simpler to have a fixed framerate. I just don't see the necessity for repeated events, if realtime input (via sf::Input) is actually needed. I have never felt the need for such a feature in SFML...

By the way, because you said there is a lot to do yourself: I implemented an Action system in my library (see signature) that should make event/input handling in SFML 2 simpler and more uniform. Just in case you're interested, an (incomplete) example might look like this:
Code: [Select]
thor::ActionMap<std::string> map;
map["left"] = thor::Action(sf::Keyboard::Left);
map["right"] = thor::Action(sf::Keyboard::Right);
map["exit"] = thor::Action(sf::Keyboard::Escape) || thor::Action(sf::Event::Closed);

// in main loop
if (map.IsActive("left"))
    // move character left
if (map.IsActive("right))
    // move character right
if (map.IsActive("exit"))
    // exit game
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

vlad

  • Newbie
  • *
  • Posts: 9
    • View Profile
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #13 on: July 15, 2011, 11:48:25 pm »
Agreed, the name "readInput" is ill-suited to what it actually does, but it used to actually just read the inputs.
I should mention that I'm currently just beginning to discover SFML, so this program is just me fooling around with no real structure yet.
When I'm skilled enough I may start a game; then I'm gonna do some serious structuring, probably by stealing ideas from a variety of pre-existing games and projects.

This being said, let's get back to this framerate business:
Got the sf::Window::GetFrameTime(), I'll use it right away.
I also checked out the Thor library, but I think I have no use for it right now. Maybe when I get down to a little more serious project.

I'll mark this topic as solved since I feel we've been through the issue.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
[Solved] How to adjust the delays involved in KeyRepeat?
« Reply #14 on: July 16, 2011, 12:51:35 am »
Glad I could help :)

I think you should just try different approaches, you will eventually find out which ones are the most appropriate. Just be aware that even though SFML and SDL cover similar functionality, the way to use it can differ much in both libraries. A lot of things have even changed from SFML 1 to SFML 2, for example sf::Input doesn't exist anymore. I suggest to begin with a recent Git revision of SFML 2, then you avoid to adapt big parts of existing code.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: