5
\$\begingroup\$

Context of the question :

When developing a game using Game State Management I came across a problematic when it came to handling user input : I want my game to retrieve user input a single way, but to handle it in a completely different way, depending on the context.

For example, the [Up] key will always mean "Menu Up" when you're in a menu, but if you're in the game, it might do different things, depending on the key bindings. Another difference would be, for example, that in a menu, a .5sec KeyDown on a key should be interpreted as a single command, but when you're in game, a .5sec KeyDown should often be seen as a .5sec movement / burst / charge shot / etc...

Then way I though about to achieve this result is the following :

  • Have an InputState class that keeps the current and previous Keyboard/Gamepad input states, just like the usual InputState class. Have this InputState class implement all the methods I would need in all the different contexts.
  • Create an Interface per context. For example, IMenuInputState, IGameInputState, ICutsceneInputState, etc. These interfaces would only contain the method definitions related to the context.
  • Have the InputState implement all the I[...]InputState interfaces. If two or more context need the same method, the same implementation would be used.
  • In the ScreenManager's Update method, the InputState would be Updated, but depending on which screen must handle the InputState, a different I[...]InputState would be sent. Even though the screen could access the other methods by casting the interface, only the contextual methods would directly be usable.

My question is the following : Is my idea a proper / common way of handling this issue?

If it is, could you tell me the name of that "pattern" or direct me to some online resources so I can read on that and avoid the known pitfalls. If it's not, how would you suggest I handle the problem?

Note: I know this question is borderline since the answer is partially subjective but I'd appreciate some help on this issue since I think it's a critical decision in my project.

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

If I am understanding, then you are saying that you will have a class called InputState that implements many interfaces. Then, other classes should never use InputState, but rather, pick an interface that applies to them.

With this model, you will be losing the advantages of inheritance. All of the code will be in one class, InputState, and the way of accessing that class becomes less clear. These kinds of statements should be a red flag in object-oriented languages:

Have this InputState class implement all the methods I would need in all the different contexts.

How about something like this:

  • InputState receives all inputs and reports on them
  • ContextualInput is a class which defines all of the shared contextual methods
  • MenuInput, GameInput, CutsceneInput all extend ContextualInput and have context-specific methods

InputState will only have general methods such as InputState.isKeyHeld(), InputState.getMousePosition(), or InputState.getAccelerometer().

ContextualInput holds a reference to the InputState object, which can be easily swapped out when you want to do testing and supply fake user input. It can also have methods that are shared among all contextual inputs, such as ContextualInput.getLastAction().

Each of the classes that extend ContextualInput implement their own methods that are completely abstracted from the way they are triggered. You could use a publish/subscribe pattern for other classes to be notified of these events:

  • MenuInput.onMenuOpen()
  • CutsceneInput.onAdvanceSlide()
  • GameInput.onCharacterJump()
\$\endgroup\$
2
  • \$\begingroup\$ Using this method, in "MenuInput" (or any other) I would see the context specific methods, but I'll also see some generic methods that I might not need. I think I'll do something similar to this, but the ContextualInput will define methods with the "Protected" keyword, and [Specific]Input will use these method in public context specific methods. \$\endgroup\$
    – Tipx
    Dec 4, 2011 at 20:34
  • \$\begingroup\$ I ended up doing mostly what is suggested in this answer, the inheritance and such, but not the event driven part. My ScreenManager creates and update the common InputState which is then passed around the different screens. The different context (group of screens) each have their own [Specific]InputState which points to the common InputState. Thanks for your input, it's much appreciated. \$\endgroup\$
    – Tipx
    Dec 5, 2011 at 0:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .