1
\$\begingroup\$

I'm having trouble finding the best approach to registering an instantaneous user key-press with MonoGame (where the key has been held down and then released), using events in C#. Unlike the click of a mouse button where only two events are usually required, it seems to me that a keyboard would require a considerable number of events where it would seem infeasible (and incredibly messy) to declare them all. I don't want to have classes individually handle the input themselves by checking the current keyboard state against the last etc.

This is the solution I've come up with, but something tells me it isn't very well designed.

public static class Input
{
    private static KeyboardState ks, ks_old = Keyboard.GetState();

    private static Dictionary<Keys, List<Action>> OnKeyPress = new Dictionary<Keys, List<Action>>();

    public static void AddKeyPressHandler(Action handler, Keys key)
    {
        if (!OnKeyPress.ContainsKey(key))
            OnKeyPress.Add(key, new List<Action>());
        OnKeyPress[key].Add(handler);
    }
    public static void Update() //Update function called every game update
    {
        ks = Keyboard.GetState();

        foreach (Keys key in Enum.GetValues(typeof(Keys)))
            if (!ks.IsKeyDown(key) && ks_old.IsKeyDown(key) && OnKeyPress.ContainsKey(key))
                foreach (var handler in OnKeyPress[key])
                    handler();            
        ks_old = ks;
    }


}

With the current setup, objects needing to handle a key-press subscribe their methods in the following way in their constructor:

Input.AddKeyPressHandler(delegate() { Input_OnAPress; }, Keys.A);

What is the optimal way to handle keyboard input with MonoGame? Are there any obvious pitfalls with my code, functionally or design-wise?

\$\endgroup\$
1
\$\begingroup\$

For all intents and purposes what you have is essentially the Observer pattern in that you have an input class that maintains a list of callbacks or input handling objects. Other objects can then register with the input system to be notified when certain things happen(in this case when each key has been pressed).

I might extend this system to allow users to also register for when a key has been released as opposed to just when a key has been pressed; to allow you to do this if might be worthwhile keep some class that would be updated that maintains the current state of the key press/release. This could also be made more generic to allow us to do the same for mouse presses, gamepad presses etc.

\$\endgroup\$
  • \$\begingroup\$ Thankyou! I was hoping the idea I was trying to convey had some formal name. \$\endgroup\$ – Xoanon Jun 29 '16 at 1:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.