Hi. I'm relatively new to more serious game programming, having made some toy stuff in the past using various languages and frameworks, but I'm trying to learn more about game architecture. Right now I'm trying to wrap my head around how input is handled in various games. I realize this may change depending on the game and even hardware being used, but any insight is appreciated.
I'm currently using Love2D and Lua, but the examples I've provided are in Python (for clarity).
When I started writing my game, I was polling for user input during the update interval from each object. So I had something like this:
while True:
for object in game.object_list:
object.update()
I've omitted some things, but I'll add that I'm using a fixed timestep.
There were a few problems with this approach:
1) If the user changed input, such as released a key, mid-update, some objects might react as though the key were pressed while others would not. This effect is even more noticeable when there is more going on in the update loop.
2) It is possible that the user does something like presses and releases a key before input is even checked, in which case that input is essentially lost completely.
The solution to the first problem was to check for input once at the start of the update loop (say by storing it in an array), and then polling that array while updating game objects rather than checking the input directly from each game object.
while True:
InputManager.update()
for object in game.objects:
object.update()
This still has the second problem though.
Thus, I started looking at the callback functions more closely. I am giving the following: key_pressed, key_released, mouse_pressed, mouse_released.
After doing some research, it seems the best way to handle input is to push events into a queue when they arise and then empty that queue during fixed update calls. The callback functions fire every time the corresponding event occurs, so I would push events onto the queue from them.
def key_pressed(key):
InputManager.queue.push(KeyDownEvent(key))
Now we get to the meat of my question: what do I do with this queue? There are a few ideas that occur to me and none seem correct. E.g.
while True:
while InputManager.queue.has_next():
for object in game.objects:
object.handle_input(InputManager.queue.next())
for object in game.objects:
object.update()
I guess my question is: how do I cleanly handle input for my game once I've captured it and pushed it into a queue?