1
\$\begingroup\$

I am a beginner in anything with game development. I written a small prototype in which i can move a square around with the arrow keys. For that i use SFML.

At the moment i experiment around with my Event System: First, to keep things simple, i was polling for the arrow keys using sf::Keyboard::isKeyPressed(), which works fine for this small kind of "game"

// in handleUserInput():
if(Keyboard::isKeyPressed(Keyboard::Left))
{
        player_.moveLeft();
}

// in player the player class:
void moveLeft()
{
    velocity.x = -x_speed; // sf::Vector2f
}

// in my player-class update() method:
void update()
{
// Out of bounds check and so on...
shape.move(velocity);
velocity.x = 0;
velocity.y = 0;
}

With this i was able to move horizontally, vertically and diagonally.

Then i moved to create my "real" EventSystem based on callbacks. It wraps around sf::Window::pollEvent(). E.g. i register a callback method for the event type sf::Event::EventType::KeyPressed. So i changed my code to first register for the movement keys

event_system_.registerCallback(sf::Event::KeyPressed, [&] (const sf::Event& event)
    {
        switch(event.key.code)
        {
        case sf::Keyboard::Left:
            log->info() << "Moving Left";
            player_.moveLeft();
            break;
        case sf::Keyboard::Right:
            log->info() << "Moving Right";
            player_.moveRight();
            break;
        case sf::Keyboard::Up:
            log->info() << "Moving Up";
            player_.moveUp();
            break;
        case sf::Keyboard::Down:
            log->info() << "Moving Down";
            player_.moveDown();
            break;
        case sf::Keyboard::Escape:
            window_.close();
            break;
        }
    });

The problem i encountered was, that i couldn't move diagonally anymore. After adding the loggin parts i found out, that when i keep two arrow keys pressed the only event that gets fired over and over again was the key pressed latest (e.g. i try to press Left & Down and pressed the Down-Key slightly later the Down-Event would be captured over and over again and the Left-Event only once).

After that i changed my code not to reset the velocity in my player's update-method and also registered for sf::Event::KeyReleased so that it would reset the x/y-part of the velocity when the corresponding key was released.

event_system_.registerCallback(sf::Event::KeyReleased, [&] (const sf::Event& event)
    {
        switch(event.key.code)
        {
        case sf::Keyboard::Left:
        case sf::Keyboard::Right:
            log->info() << "Stopped moving horizontally";
            player_.velocity.x = 0;
            break;
        case sf::Keyboard::Up:
        case sf::Keyboard::Down:
            log->info() << "Stopped moving vertically";
            player_.velocity.y = 0;
            break;
        }
    });

But somehow this does not seem right to me (But it wouldn't seem right to me to poll for every single possible input manually - So i think events is the things to take). Could anyone give me a hint what i am doing wrong and how to do it better?

Kind Regards

\$\endgroup\$
  • \$\begingroup\$ Some people (like me) like to have a state for each key. A variable named, for example, key_right that we put to true when it is pressed and false when it is released. We then look up that state on update to move accordingly. \$\endgroup\$ – Alexandre Desbiens Jun 15 '15 at 20:25
  • \$\begingroup\$ @AlexandreDesbiens How do you look up the state would be the question: Do you poll, or use callbacks? \$\endgroup\$ – Incubbus Jun 16 '15 at 10:44
  • \$\begingroup\$ You use both the onKeyPress and onKeyRelease callbacks to change the state of the key, but afterwards, you poll this state. \$\endgroup\$ – Alexandre Desbiens Jun 16 '15 at 12:47
3
\$\begingroup\$

I would personally use the keyboard class that allows you to query the state of keys instead of waiting for an event.

The documentation is here

One of the reasons I prefer this method is that you can check the status of the key from almost anywhere in the code, and you don't have to store the state of the keys yourself.

f::Keyboard can retrieve the state of a key at any time (you don't need to store and update a boolean on your side in order to know if a key is pressed or released), and you always get the real state of the keyboard, even if keys are pressed or released when your window is out of focus and no event is triggered.

The other obvious advantage is that you can check the state of multiple keys at the same time, hence making it easy to detect key combinations :

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && sf::Keyboard::isKeyPressed(sf::Keyboard::Down))player_.moveDownLeft();
\$\endgroup\$
  • \$\begingroup\$ Could you elaborate why you prefer to poll? \$\endgroup\$ – Incubbus Jun 16 '15 at 12:42
  • \$\begingroup\$ Edited the answer \$\endgroup\$ – Lectem Jun 16 '15 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.