1
\$\begingroup\$

I wonder what the best way is to move the player. Is it best to always check for movement like I do in the first example of is it better to only access the movement function via the input function like the 2nd example?


-EXAMPLE 1-
while(running)
{
    while(event)
    {
      player.input();
    }
    logic();
    render();
}
logic()
{
    player.move();
}


-EXAMPLE 2-
while(running)
{
    while(event)
    {
      player.input();
    }
    logic();
    render();
}
player.input()
{
    player.move(direction);
}
player.move(int dir)
{
    if(dir == left)
    {
        xvel += 1;
    }
}

I hope I explained it right. Thanks in advance.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

I assume you mean whether you should be doing active polling or listening to events.

  1. Active Polling means that you check the state of your input devices on every update. For example, the Logic() (or Update() or Tick()) function of your character could contain: if (input.isPressed(KEY_RIGHT)) { positionX += 10; }.
  2. Events on the other hand let you react to events generated by your input device. For example, if you press the right arrow key on your keyboard, a KeyboardKeyEvent(KEY_RIGHT, ACTION_PRESS) event might be launched. You can then register your character object to listen for these events.

In the first case, you will be checking all buttons every frame. Let's say you have 50 objects in your gameworld, and they need to respond to five different keys on average. If you are running at 60 frames per second, you'll be launching 50 * 5 * 60 = 15000 polling function calls per second.

In the second case, the input device (or some manager component inbetween) takes the initiative to contact all objects that are interested in listening to keyboard event. Let's say you still have 50 objects in your gameworld, they still respond to five different keys on average, and you are still running at 60 frames per second. The important thing to note is, that object code is only called when an event happens. Let's say you press 10 keys every second (which would be a lot). This means the number of calls made will be 50 * 10 = 500.

For active polling, the number of calls relates to the the amount of buttons that an object responds to, the amount of objects in your gameworld and the framerate of your game. For events, the number of calls relates to the amount of actual, physical button presses and the amount of listeners.

Events are a great choice for checking input, as input events occur sporadically (aka. relatively far and few inbetween).

An additional advantage of events is:

  • you can apply filtering in some management component, so that you need to send even fewer events (eg. an object might only be interested in the space bar, and only in key presses (not releases or holds)). This further decreases the number of calls.
  • once you've registered yourself, no more checking is required in your logic code. You are guaranteed that a callback will launch when input is detected, and you can cleanely handle that button press in a separate functions

Some disadvantages are:

  • you need to register all of your objects beforehand, meaning you have quite a bit more initialialization work
  • an eventing mechanism can be more tricky to set up. You'll need to implement a management component where objects can register themselves. This management component should be intercepting actual input events from input devices (eg. GLFW keyboard events if you were doing OpenGL in c++) and call the correct callback methods of the listeners.
\$\endgroup\$
3
  • \$\begingroup\$ Your right on the performance part, that is why I started to program like example 2, but I am running in some tricky issues like stopping immediately with attacking (animation) when the button is released. I could fix this with if(button A) do Attacking() else stopAttacking() but when a button has multiple functions there has to be a lot of logic build in the input method. That is why I asked this question. Still not sure which direction I'm gonna go. \$\endgroup\$
    – NoParanoia
    Apr 16, 2015 at 7:36
  • \$\begingroup\$ Yeah, event-based logic can be more tricky, as you are only executing code on buttons events themselves and not the frames inbetween. Related to StopAttacking(), you could have different callback functions for different button actions. Eg. you could bind StopAttacking() to the BUTTON_RELEASED action and StartAttacking() to the BUTTON_PRESSED action. These functions could set a flag, or switch a state in your character's state machine, allowing you to execute the WhileAttacking() behavior in your Update() function. You might be interested in this article on state machines: bit.ly/1uGxVv6 \$\endgroup\$ Apr 17, 2015 at 11:15
  • \$\begingroup\$ Great article, it is certainly going to help me. As for the BUTTON_RELEASED action, that is exactly what I was going to do. Thanks you've me helped a great deal. \$\endgroup\$
    – NoParanoia
    Apr 17, 2015 at 12:29
0
\$\begingroup\$

In your EXAMPLE 1, you're gathering all your player input first, and then doing the move as part of logic().

In your EXAMPLE 2, you're moving the player-object as part of gathering the input.

EXAMPLE 2 is ok if there's nothing else that influences the player besides the user input.

But usually what happens to each game object (including the player) might be affected by various things going on. If you keep working on Example 2, you might find more and more "logic" crammed into "input".

Here's a pattern that has served me well in many things (software design, code structure, major life decisions, &c): Gather, Analyze, Act.

So I'd go with EXAMPLE 1 as the "better" layout.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for your reply. I was always programming my "games" like example 1 but mow I started to put a loop together like example 2 and was (like you say'd) cramming more and more logic into input. I think I'll going to change it back to example 1. \$\endgroup\$
    – NoParanoia
    Apr 16, 2015 at 7:18

You must log in to answer this question.

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