Handling both Touch and Mouse Input with Monogame

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<IInputController> _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<IInputController>();
            
            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<IInputController>();
            
            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<IInputController> 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.

2 thoughts on “Handling both Touch and Mouse Input with Monogame

  1. Simon Jackson

    Nice example but you go in to a bit more depth on your setup, detailing the sample interface or better yet, provide a simple example project with the implementation?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *