Sign in to follow this  
vecchia

Where to handle input logic

Recommended Posts

vecchia    103
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?

Share this post


Link to post
Share on other sites
Serapth    6671
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.

Share this post


Link to post
Share on other sites
c_olin    197
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.

Share this post


Link to post
Share on other sites
vecchia    103
[quote name='Serapth' timestamp='1312990865' post='4847183']
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.
[/quote]
yes, I need to handle more keys simultaneous

[quote name='c_olin' timestamp='1312991076' post='4847186']
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.
[/quote]
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

Share this post


Link to post
Share on other sites
Gangi    100
[quote name='Serapth' timestamp='1312990865' post='4847183']
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.
[/quote]

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.

Share this post


Link to post
Share on other sites
Krohm    5030
[quote name='Stefano A.' timestamp='1312989685' post='4847178']At the moment I'm handling it inside the WM_KEYDOWN WM_CHAR and WM_KEYUP messages.[/quote]As user of a non-standard keyboard layout, I want to [b]thank you[/b] 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!


[quote name='Stefano A.' timestamp='1312989685' post='4847178']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?[/quote][i]DirectInput [/i]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 [b]not [/b]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.

Share this post


Link to post
Share on other sites
vecchia    103
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?

Share this post


Link to post
Share on other sites
szecs    2990
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".

Share this post


Link to post
Share on other sites
vecchia    103
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?

Share this post


Link to post
Share on other sites
yckx    1298
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

Share this post


Link to post
Share on other sites
szecs    2990
[quote name='yckx' timestamp='1313009248' post='4847317']
I would store input state in WndProc and poll it to determine what events to fire in the main loop. This completely separates events Tom 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...
[/quote]

Plus input events could come from an AI bot too for example...

Share this post


Link to post
Share on other sites
vecchia    103
ok but how should I determine which events to fire in the main loop if I don't call immediatly after the key press the listeners?

Share this post


Link to post
Share on other sites
yckx    1298
[quote name='Stefano A.' timestamp='1313013294' post='4847359']
ok but how should I determine which events to fire in the main loop if I don't call immediatly after the key press the listeners?
[/quote]
A simple state array could be a bool array. On WM_KEYDOWN set the relevant array element to true; on WM_KEYUP set it to false. In your main loop, for each true element, fire its corresponding event.

Share this post


Link to post
Share on other sites
vecchia    103
there is a problem, if I store only the state of the keys how can I know the difference from WM_CHAR and WM_KEYDOWN messages? I mean, for example let's say that the user press the W key: it could be the action to move the player but also the action to write that letter in the chat...

Share this post


Link to post
Share on other sites
szecs    2990
Well, that's implementation detail. You program it.

Anyway, Game states can affect the dispatching too. You can have two different buffers for character input and for key input. And so on.

Stop talking and start programming! :P

Share this post


Link to post
Share on other sites
rip-off    10976
Think about how other games you play work. When you want to type a message, you usually need to press a particular key to get the chat box up. Once it has the [b]input focus[/b], the keys you press no longer move your character.

You need a way to model input focus in your game.

Share this post


Link to post
Share on other sites
Krohm    5030
[quote name='Stefano A.' timestamp='1313093846' post='4847886']there is a problem, if I store only the state of the keys how can I know the difference from WM_CHAR and WM_KEYDOWN messages? I mean, for example let's say that the user press the W key: it could be the action to move the player but also the action to write that letter in the chat...[/quote]Sigh. I knew I was talking too early. You have not understood what's the difference between a character and a keypress.

This is NOT implementation detail.

Sigh. It is just so sad that in 2011 people just go around with shaders and still don't understand the most basic thing of keyboard processing.

So... take notice key buttons != text generated. Text != glyph. Go to your keyboard settings and mess a bit with it. If you don't want to see, [url="http://en.wikipedia.org/wiki/Keyboard_layouts"]http://en.wikipedia....eyboard_layouts[/url].

You don't mix the two together. And by the way, components typically consuming key presses are rarely involved in character processing anyway.

[quote][url="http://www.gamedev.net/topic/186067-text-input/"]October 2003[/url]:
[b]Q:[/b] I still need a good method of getting keyboard input. Does anyone have any ideas that don''t involve testing for individual keys? I''m sure there''s some way I could do this using the WM_KEYDOWN scenario
[b]A:[/b] WM_CHAR is the way I get text input from windows. ... I wouldn''t use the WM_CHAR for navigating a GL scene though but you can use WM_KEY messages [for this]...

[url="http://www.gamedev.net/topic/596735-directinput-for-azerty-keyboards/page__view__findpost__p__4780974"]March 2011:[/url]
[b]Q:[/b] What can I do to make DirectInput translate the scancodes it receives to my current keyboard layout? ... DI only registers an 'A' keypress when I press 'Q'.
[b]A:[/b] This is correct behavior, because AZERTY(A) is QWERTY(Q). Just writing "B" on a button does not make it generate char('b'). DirectInput (as well as WM_KEYDOWN) works on "scan codes" or "virtual key codes" which are roughly "the position of the button on the physical keyboard".
It seems like [b]you have not correctly assimilated the [color="#8b0000"][u]important distinctions[/u][/color][/b] between
[list=1][*]The physical button being pressed on the keyboard ( suppose it's QWERTY(Y) )[*]The sticker applied to the button pressed ('Y' on QWERTY)[*]The character generated - 'y' or 'Y' on QWERTY, 'f' or 'F' on my layout - depending on window manager preferences.[*]The glyph associated to the character in the given context (can be pretty much everything according to TrueType management)[*]The scan code uniquely associated to the physical button pressed.[/list]
What you're doing with DI and WM_KEYDOWN is to work on (5). Which is the correct thing to do for "actions". Keyboard layout should really be considered only for text input.

[url="http://www.gamedev.net/topic/605543-directdraw-virtual-buttons/page__view__findpost__p__4831233"]July 2011[/url]
[b]Q:[/b] Also, is there any input on which is better for mouse and keyboard input (not critical on speed just dependable) win32 or direct input. b/c direct input is a hunk of poo.
[b]A:[/b] Yes, it is. Do not use DirectInput ... for character input, WM_CHAR works just fine. It has several advantages compared to DIY-input management such as 1) always correctly adapted to active locale and 2) behavior coherent with user settings (key repetitions per second etc).
For keyboard buttons, most of the time WM_KEYUP and WM_KEYDOWN work just fine... sometimes they get stuck when switching focus and such but I don't think that's a problem in general....[/quote]

I could go on forever dude. So I look forward to declare a day I will have taken this crusade for a decade. I want to thank all the people who actually also fight this apparently hopeless battle and all the people properly using the search button.

Share this post


Link to post
Share on other sites
Katie    2244
Actually, you CAN call C++ code just fine from WinProc; including allocating memory and the like. What you must not do is allow any thrown exceptions to propagate out of WinProc.

Share this post


Link to post
Share on other sites
szecs    2990
Um, I don't get this hopeless battle thing. As far as I remember, almost everyone got the WM_CHAR thing after explaining them. It's not one person who ask the same question again and again, but individual persons.

Dealing with input, character or key, is implementation detail after a point. I was implying that one cannot design everything up front, especially if one is an inexperienced newbie. One has to start the actual programming and solve problems when one meets them. What the OP does seems to be temporizing... (a'la "stupid over-preparedness ")

Share this post


Link to post
Share on other sites
vecchia    103
[quote name='Krohm' timestamp='1313138355' post='4848138']Sigh. I knew I was talking too early. You have not understood what's the difference between a character and a keypress.
This is NOT implementation detail.

Sigh. It is just so sad that in 2011 people just go around with shaders and still don't understand the most basic thing of keyboard processing.

So... take notice key buttons != text generated. Text != glyph[/quote]
First thing, I'm here to learn, noone born genius, even you. Also, I understood that pressing W keyboard button (for example) doesn't mean that on the screen I will see W, this is why I'm asking how could I split the WM_CHAR and WM_KEYDOWN messagesto handle them properly when I need to type in a chat and when I need only to handle input to move the player

Share this post


Link to post
Share on other sites
popeax    100
I might set some flags in the Inputclass instead of having it send events (WndProc is already an event listener I'm not sure one needs more). Then in the main loop update the player objects and have them access the inputclass. If you are worried about "proper" it might help to do some object diagram. For a small project "proper" doesn't matter so much.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this