Skip to main content
GameDev.net gamedev.net
🔒 Locked

Customizable User Input

Started by WebsiteWill Jun 28, 2007 at 1:42 PM 7 replies 750+ views
Original Post
WebsiteWill
WebsiteWill
Howdy: I'm working on a user interface and I am at the point where I have the interface rendering as I want, with limited controls. I can have windows, labels, buttons and not much else at the moment. What I am having a hard time figuring out is how would I let user input be customizable for the application? The GUI is skinnable through an XML skin file. I want to allow users the ability to have their button perform their chosen action. So, playerA might have a SHOOT button on the left of their screen and playerB might have the SHOOT button on the right. This is done through the XML skin. Now, input, I want players to be able to customize their keyboard shortcuts and this is where I have hit a wall. PlayerA might SHOOT with the Z key, PlayerB might shoot with the G key, etc. How would one design this? Also, the shortcut keys should affect the GUI so, if I press Z to SHOOT, the graphics engine should update with my shot, other logic should happen AND the GUI needs to disable the SHOOT button until the timeout elapses and I can SHOOT again. I've found lots of tutorials on how to render the GUI and that is not at all an issue. My problem is how would I translate the input into game functions that would be called when I Press a button on the GUI or press a key on the keyboard. TIA, Webby
Antheus
Antheus
Quote:
My problem is how would I translate the input into game functions that would be called when I Press a button on the GUI or press a key on the keyboard.


You don't.

Define actions. ShootAction, MoveForwardAction, JumpAction, ExitGameAction, ....

The natural mapping to design is: http://en.wikipedia.org/wiki/Command_pattern

If that is unsuitable for your current application, then you have other options. Define constants for actions, and use those to determine what to do. Or possibly use callbacks/events/function pointers to map your triggers with corresponding actions.

Once you have defined your actions, define action-specific behaviours. Action-with-cooldown would disable the source from where it was triggered, for example.

Your actions will always need be something like (ActionType, Source) tuples. Source will be something applicable to providing feedback. It could be an interface with setCooldown( milisec ) or similar.

The Source parameter can obviously be a list, that will be notified whenever an action occurs. So you could link arbitrary number of GUI elements to it, as well as other notifications that might occur.
WebsiteWill
WebsiteWill
OK, I got that but there is still a piece missing.
I guess it's an ordering thing I'm not sure about.

Back to the shoot button:

There is a command called "SHOOT" that happens when the SHOOT button is pressed OR when the Spacebar is pressed.

If I use the command and just make the button AND the spacebar listeners then the command will happen twice. Obviously the ShootCommand object would need to know how to tell the graphics engine the perform the shoot animation and update the UserInterface (gray out the shoot button).

So I guess the ShootCommand would have logic in it to determine how often if can be called so that if the user clicks the button and then hits the spacebar, the second command would get ignored unless the specified time has elapsed?

This is a tricky thing to wrap ones head around.

Thanks for the input,
Webby
WebsiteWill
WebsiteWill
I've got the command pattern set up and I like it, it's easy and it's nice, but it is still posing a problem for me.

In a setting where input is interpreted differently depending on game state, I am having a hard time getting everything managed.

For instance, while pressing the UP arrow and the game is not in UI focus mode I want to make the character run. While holding UP if the player presses LEFT I want the character to run while turning to the left (typical FPS movement).

However, UP and LEFT have a different function if the input happens on a textbox. So, here's my problems.

Say I'm holding UP to run, then, while holding UP I click on a textbox on my interface then press the LEFT key. Should I send a UP Key released command to the game state to stop running when the GAME state loses focus, or do I continue to process the UP arrow by moving the character until it's released, even though focus is on the GUI?

If I transmit the UP key release but the player is still pressing the key, what happens then? My game would think the key was up when it's really pressed.

Confused...
Webby
Extrarius
Extrarius
Those options are all entirely program-specific. In some programs, it might be better to 'release' all keys when you switch focus, while in others it's better to leave the state the same (though if you don't send 'key up' immediately on a focus change, you'll need some extra logic to make sure that when focus is switched back, the game will get a 'key up' message if the key is now released, otherwise the key will 'stick' down even if it's not actually pressed).

As far as changing functions in different modes, you could just have multiple input maps (map in C++), store them in a list sorted by priority (so the character-action map is first when in game mode, and the gui-action map is first when interacting with the GUI). Then, when a key is pressed, go through the list and check each map for a command assigned to that key. Execute the first command you come accross, and you'll automatically get UI actions when it's in focus and character actions when it's not.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
WebsiteWill
WebsiteWill
Well for context purposes, it would be geared towards an RPG or FPS style of game but should work similarly to RTS genre.

What is really daunting me is that there doesn't seem to be a clear line there between interacting with UI and game since it's completely conceivable that I could be interacting with the game by running (holding the UP arrow) and while running I could be clicking various buttons on the GUI (run faster, jump, etc).

So the GUI would have to detect that it's been clicked and would then have to decide what to do with the run option (leave it alone if we clicked the RUN_FASTER button or stop all movement if we clicked on a textbox).

I hate to say it but, the way World of Warcraft or Everquest or Quake all handle it is pretty snazzy. :)

For all I can figure out, in WoW you can be running and still click stuff, but the minute you press the Enter key, you go into text entry mode and all movement stops (unless you are moving around with the mouse). I really don't know how they would handle all of this without a massive if-then-else structure.

You would think that documents on input schemes like this would be plentiful on Google but I have yet to find anything decent out there.

I don't think it's as simple as a state manager since these games allow you to be in multiple states at the same time (or at least they appear to).

Back to the drawing board...
webby
Extrarius
Extrarius
Well, if you use the priority system I mentioned, normally the character actions would be in priority, then when you click a button UI priority takes over, but since the general UI input map doesn't have anything for the up arrow, it'd still be doing what it was doing before (making you run forward). Once you click on a text box, list box, combo box, etc, the input map for those controls would come on top and would thus override the arrow keys to act appropriate to those controls.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
WebsiteWill
WebsiteWill
Ok, but what happens to the currently occurring action? If a textbox comes into focus do you send the STOP_RUN command to simulate the run button being released and then process the new UP_ARROW_DOWN presses in the context of the textbox? Or do you continue to let the character run because the last command officially send to the game update was to RUN?

Webby
Extrarius
Extrarius
That's up to you. The second method just means you don't do anything special when switching context, while the first just means you loop through the keys and check if the new keymap overrides the command AND the key is pressed, then execute the key-release command before switching contexts. Just pick whichever you think fits your game best.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.