Where to handle input logic

Started by
25 comments, last by vecchia 12 years, 8 months ago
Hi all, I'm developing a little game and I have some doubts about where to handle my onpit logic. At the moment I'm handling it inside the WM_KEYDOWN WM_CHAR and WM_KEYUP messages. The rendering is hadled in the main application loop. Is this correct or should I use something like the directx input that keep an array with the current buttons state? I mean, should I call a function that updates this array inside the main loop or should I continue with my actual method?
Advertisement
Do you need to handle multiple simultaneous key presses? If no, don't worry about the state array, if you do, you need the state array.
It is desirable to have the input handling (Windows events in your case) independent of the game logic. The simplest way to do this in your case is to have functions like [font="Courier New"]MovePlayer(Vector2 direction) [/font]or [font="Courier New"]QuitGame() [/font]that are called when certain windows events happen. If you are using OOP then this can be implemented more elegantly using event dispatchers/listeners.

I would not recommend constantly checking keyboard state through your game logic. The code for moving the player around does not need to know about keyboard input, only how to move the player.

Do you need to handle multiple simultaneous key presses? If no, don't worry about the state array, if you do, you need the state array.

yes, I need to handle more keys simultaneous


It is desirable to have the input handling (Windows events in your case) independent of the game logic. The simplest way to do this in your case is to have functions like [font="Courier New"]MovePlayer(Vector2 direction) [/font]or [font="Courier New"]QuitGame() [/font]that are called when certain windows events happen. If you are using OOP then this can be implemented more elegantly using event dispatchers/listeners.

I would not recommend constantly checking keyboard state through your game logic. The code for moving the player around does not need to know about keyboard input, only how to move the player.

I'm alredy using OOP with event dispatchers/listeners, this is what I'm doing in the WM_* messages. I actually call the main input class passing a generated event that will be dispatched trought all the listeners

Do you need to handle multiple simultaneous key presses? If no, don't worry about the state array, if you do, you need the state array.


Serapath is right. But I think there are some exceptions depending on the results you want to achieve. For example, if you want to move a character inside a RPG game, one thing I like is use the arrow keys is to give priority to some movements. I mean, if I'm going down but I want to avoid an obstacle I have to turn right and then continue going down, what I do is give priority to the last pressed key. Differences in key pressing if you want to go down and avoid an obstacle between the two approaches:

-Without priority: Press down_key + release down_key + press right_key + release right_key + press down_key

-With priority: Press down_key + press right_key + release right_key

With key priority I find it easier to drive a character and it's not obvious that you have to use a state array or something similar.
At the moment I'm handling it inside the WM_KEYDOWN WM_CHAR and WM_KEYUP messages.
As user of a non-standard keyboard layout, I want to thank you for realizing the important difference between button presses and characters generated. I've been stressing this for a few times, thanks god someone does that right!


Is this correct or should I use something like the directx input that keep an array with the current buttons state? I mean, should I call a function that updates this array inside the main loop or should I continue with my actual method?
DirectInput has been deprecated for a while right now. Don't even think about it. It seems it's emulated on top of KEYUP/DOWN and CHAR. Do not use it for keyboard management, nor mouse.

You really have no chance than storing everything in an array of some sort for later processing. In general, do not make "complex" calls from [font="Courier New"]WndProc[/font], where "complex" means "could throw an exception". Whoops. That means you cannot allocate memory using [font="Courier New"]new[/font]! Unfortunately, [font="Courier New"]WndProc [/font]is defined in C terms. That means C++ features are not guaranteed to work properly, especially when dealing with exceptions. Now, it might eventually happen to work: i don't know. And I don't even want to figure out. This is a C func, and must behave as such.

You absolutely want to have a better separation between input and processing. Processing "actions" is typically high gameplay-level behavior, having separation is heavily recommended. At a certain point, you'll find yourself in the future, with your system having no knowledge at all about those "actions". I think this is good.

Previously "Krohm"

so should I handle the key press/release in the WM_* messages and store their state in an array. But when should I dispatch the events, in the main loop before the graphic rendering or when the WM_* happens?
Well, you could "poll" input state. And/or use event triggers that are triggered inside WM_* messages and listened in the logic. Usually this polling and/or listening should go inside the main loop after the "message pump".
what I don't understand is, if I trigger the WM_KEYDOWN, WM_CHAR, WM_KEYUP events what should I do? Dispatch the event to the listeners immediatly or simply store in the array the new status of the key and in the main loop call the listeners?
I would store input state in WndProc and poll it to determine what events to fire in the main loop. This completely separates events from the window, which eases things like allowing the player to remap keys. Which reminds me that I need to add a key-remapping interface to my menu...

Edit: fixed "Tom the window." damn iPhone miss-autocorrecting my typos :P

This topic is closed to new replies.

Advertisement