0
\$\begingroup\$

I recently had the occasion to work on a game, during a game jam at my college, and it really got me into it, so I've decided to start something more polished with a friend of mine. During the game jam, I made a top-down 2D hack'n'slash with a capped frame rate, thinking it would be easier. However, I ran into some problems for animations, and realized that capping the frame rate wasn't the best solution, as it would also cause the game to run slower on weaker hardware.

I updated the engine, so that it would use variable time steps. However, I've read a lot about patterns, and realized that variable time steps are highly deprecated. After some reading, I thought I'd settle for something like this:

const sf::Time MS_PER_UPDATE = sf::seconds(1 / 60);

sf::RenderWindow window(sf::VideoMode(800, 600), "GameEngine");

sf::Clock clock;
sf::Time lag = sf::milliseconds(0);

while (window.isOpen()) {
    sf::Time elapsed = clock.restart();
    lag += elapsed;
    sf::Event event;
    window.pollEvent(event);

    if (event.type == sf::Event::Closed) {
        window.close();
    }

    // Where to process input?
    while (lag >= MS_PER_UPDATE)
    {
        // Update game logic
        lag -= MS_PER_UPDATE;
    }

    window.clear();
    // Rendering
    window.display();

The question is, where do I handle my input? In my last project, I passed the event polled in the update function (something like update(event, dt)), and handled user input there; I'm wondering if it is actually the way it is supposed to be done. Since I'm only polling one event per frame, I'm wondering if it would significantly affect the user experience.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Where do I handle my input? [...] I'm wondering if it's actually the way it's supposed to be done.

That's the advantage of using a framework or library rather than a complete engine: It's up to you to decide based on what you want or what you need. You're not forced to either approach.

Also since I'm only polling one event per frame, I'm wondering if it would significantly affect user experience...

This can and will create massive input delays and lags, if the program is running slower for whatever reason. You should always poll all events available between drawing.


Personally I'd try handling input in your primary event loop (which you're missing right now; see the note above). Create and update some kind of state, which could be as simple as a bit field in an integer.

This encapsulation allows you to rework or replace the input handling at any time (you might not want to use SFML forever or redo something) without rewriting everything.

\$\endgroup\$
2
  • \$\begingroup\$ Regarding the event loop, I had one at first, but I realized that once an event was polled, it was destroyed. What I mean is, I basically polled every event on the queue, did my controls for the window (for example, exit) and then outside the loop passed the event to update (but that would be the last event only). Now I could have some handleInput method for the player but what would it do? In my previous solution I've updated the physics in the update method based on user input... \$\endgroup\$
    – aslad
    Feb 5, 2017 at 9:57
  • \$\begingroup\$ @aslad: That's why you should create some state to pass rather than passing events around or (worse) polling at multiple locations. \$\endgroup\$
    – Mario
    Feb 5, 2017 at 19:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .