Does anybody have any ideas for a decent strategy on handling user input from multiple input devices, such as keyboard, mouse, gamepad, joysticks, etc.
I have been going over it in my head for a while and really need to discuss these issues with the likes of yourselves!
I wrote a quick class as a test and it seems to work fine, its only for keyboard at the moment and I map the keys in the constructor (obviously this could be done in a config file and read in at game start up), the class names and such are probably not the best named but its a start, something I will probably scrap but just so you know I have at least tried something!
public class InputInfo{
InputKeys currentKeys;
public InputInfo()
{
_UserInputMap = new Dictionary<Keys, InputKeys>();
_UserInputMap.Add(
Keys.W, InputKeys.CameraForward);_UserInputMap.Add(Keys.S, InputKeys.CameraBackwards);
_UserInputMap.Add(Keys.A, InputKeys.CameraLeft);
_UserInputMap.Add(Keys.D, InputKeys.CameraRight);
_UserInputMap.Add(Keys.Up, InputKeys.CameraUp);
_UserInputMap.Add(Keys.Down, InputKeys.CameraDown);
_UserInputMap.Add(Keys.Escape, InputKeys.Exit);
} public void Update(GameTime gameTime)
{
KeyboardState state = Keyboard.GetState();
currentKeys = InputKeys.None; foreach (Keys key in _UserInputMap.Keys)
{
if (state.IsKeyDown(key))
currentKeys |= _UserInputMap[key];
}
}
/// <summary>
/// Check to see if a key or multiple keys are being pushed
/// </summary>
public bool KeysDown(InputKeys keys)
{
if ((currentKeys & keys) != InputKeys.None)
{
return true;
} return false;
}
}
[
Flags]public enum InputKeys : uint
{
None = 0x0,
Console = 0x1,
CameraForward = 0x2,
CameraBackwards = 0x4,
CameraLeft = 0x8,
CameraRight = 0x10,
CameraUp = 0x20,
CameraDown = 0x40,
CameraPitchUp = 0x80,
CameraPitchDown = 0x100,
CameraYawLeft = 0x200,
CameraYawRight = 0x400,
CameraRollLeft = 0x800,
CameraRollRight = 0x1000,
CameraZoomIn = 0x2000,
CameraZoomOut = 0x4000, //other keys
Exit = 0x8000
}
I guess having CameraThis, CameraThat, etc would probably be pointless when I could just have Up, Down, Left, Right, etc and treat that as general controls for anything if I was to say, have some kind of controller and controllable pattern thing happening, but its just an example of what I thought might be sufficient.
Any by the way this forum screwed up my code formatting (I hope no one thinks I am sensitive to comments against my code!)
Also here is an example how I check if an input button(s) is currently pushed:
if (MyGame.Input.KeysDown(InputKeys.CameraUp))
{
// Do stuff
}Anyone care to discuss this one :)
best regards
Fluxtah

Handling user input from any device
Ljhopkins
Cool thanks andyfraser, I have looked through the code and its a nice implementation, very flexible.
NozFx
What I do is read the controller input (if connected, else just clear the input struct). Then I read the keyboard, and if a button is down, poke the corresponding value into the gamepad struct. Then I read the mouse (if on Windows), calculate the delta from the last frame, and if the delta is non-zero, poke the delta in X and Y into the right stick value of the gamepad struct. Last, I dispatch this gamepad structure to the simulation system, that forwards it to the actor in charge (a vehicle, weapon or avatar, typically).
This method is fairly ghetto, but it does get the job done, and it's a lot simpler than a custom-configurable system with event delegates mapping to input primitives. It lets me get on to the actual game part with a minimum of fuss :-)
Shokino
Cool, with the mouse delta, is it worth also knowing a normalized direction the mouse is going I was thinking about doing this as the X,Y coords of the mouse are not that useful, just which way its going is I guess.
I was after something small and lightweight, flexible and used enums, I wrote a small generic class that does the trick, here is that class and the implementation for a camera enum, it only works for keyboard, however I will extend it for mouse, and maybe xbox controller (although I dont own an xbox 360 to test it with).
public class UserInput<T>
{
protected Dictionary<Keys, T> _KeyMappings;
int currentButtons;
public UserInput()
{
_KeyMappings = new Dictionary<Keys, T>();
}
public bool Check(T button)
{
if ((currentButtons & Convert.ToInt32(button)) > 0)
return true;
return false;
}
public void Update(GameTime gameTime)
{
KeyboardState state = Keyboard.GetState();
currentButtons = 0;
foreach (Keys key in _KeyMappings.Keys)
{
if (state.IsKeyDown(key))
currentButtons |= Convert.ToInt32(_KeyMappings[key]);
}
}
public void Map(Keys key, T button)
{
_KeyMappings.Add(key, button);
}
public void UnMap(Keys key)
{
if (_KeyMappings.ContainsKey(key))
_KeyMappings.Remove(key);
}
}
public class CameraInput : UserInput<CameraButtons>
{
public CameraInput()
{
Map(Keys.W, CameraButtons.Forward);
Map(Keys.S, CameraButtons.Back);
Map(Keys.A, CameraButtons.Left);
Map(Keys.D, CameraButtons.Right);
Map(Keys.Up, CameraButtons.Up);
Map(Keys.Down, CameraButtons.Down);
}
}
public enum CameraButtons
{
None = 0x00,
Up = 0x01,
Down = 0x02,
Left = 0x04,
Right = 0x08,
Forward = 0x10,
Back = 0x20,
ZoomIn = 0x40,
ZoomOut = 0x80
}
I guess this can be used in several ways, for a quick test I made my camera just include CameraInput as a member, although it would be best to make only one instance rather than for each camera! also rather than doing the mapping in the constructor I could write a parse it from a config file.
if (Input.Check(CameraButtons.Up))
{
// do stuff.
}
where Input is a type of CameraInput member.
any feedback on this would be greatly appreciated!
Peter De
Hi,
I made up a small game component to simplify user input from the keyboard, mouse and XBox gamepad.
You can find it here : http://www.xgamelibrary.com/Components/XGameInput.aspx
Full source and instructions are provided. Your comments/suggestions are very welcome.
Andy