Handling both Touch and Mouse Input with Monogame

April 12, 2014

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.



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2024