I’ve already posted a few times on handling input for Monogame. This one’s a little bit different though, and came from the fact that I had a game trying to get through certification that was repeatedly failing. What I was doing was detecting touch capabilities and, where I found them, using them; otherwise, using keyboard or mouse.
What I ended up doing was handling both. At the time this was just to get the game through certification in the Windows Store; but the more I think about it, the better I think the solution is.
Instead of maintaining a single input contoller, and assigning to it via a factory method, I maintain a list of controllers:
List \_inputControllers;
Then, instead of an if / else statement to assign to the controllers, I simply add what’s available:
// Determine how the user will interface with the game
private void HandleInput()
{
// Instantiate the controllers collection
if (\_inputControllers == null) \_inputControllers = new List();
if (\_inputControllers.Count == 0)
{
// Can we handle touch? If so, add a new controller to handle touch
Windows.Devices.Input.TouchCapabilities tc = new Windows.Devices.Input.TouchCapabilities();
if (tc.TouchPresent == 1)
{
\_inputControllers.Add(new TouchController());
}
// Can we handle Mouse? If so, add a new controller to handle mouse
Windows.Devices.Input.MouseCapabilities mc = new Windows.Devices.Input.MouseCapabilities();
if (mc.MousePresent == 1)
{
\_inputControllers.Add(new MouseController());
}
}
So, now we’ve got a list (and it doesn’t have to be restricted to 2 elements if, for example, you suddenly decide to support a thought-power interface http://en.wikipedia.org/wiki/Emotiv\_Systems).
On the update method of your game, you now simply iterate through them:
foreach (IInputController inputController in \_inputControllers)
{
inputController.HandleInput();
}
Isn’t it a bit messy having the (potentially) giant conditional statement above
Yes. So, how about this.
// Determine how the user will interface with the game
if (\_inputControllers == null) \_inputControllers = new List();
if (\_inputControllers.Count == 0)
{
TouchController.AddController(\_inputControllers);
KeyboardController.AddController(\_inputControllers);
}
And then add the AddController function as a static method; like so:
internal static void AddController(List controllers)
{
Windows.Devices.Input.MouseCapabilities mc = new Windows.Devices.Input.MouseCapabilities();
if (mc.MousePresent == 1)
{
controllers.Add(new KeyboardController());
}
}
I’m unsure if this qualifies as a “Factory” method as such, although effectively that is what it is.
Conclusion
I’m now quite happy with this approach. I can foresee future uses for the logic, so at some point, if I get time, I might transfer it all to a PCL and publish on Codeplex… assuming I can work out how to get the Windows.Devices namespace to work in a PCL.