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
InputStateclass that keeps the current and previous Keyboard/Gamepad input states, just like the usual InputState class. Have thisInputStateclass 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
InputStateimplement all theI[...]InputStateinterfaces. If two or more context need the same method, the same implementation would be used. - In the
ScreenManager's Update method, theInputStatewould be Updated, but depending on which screen must handle theInputState, a differentI[...]InputStatewould 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.
Answer
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:
InputStatereceives all inputs and reports on themContextualInputis a class which defines all of the shared contextual methodsMenuInput,GameInput,CutsceneInputall extendContextualInputand 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()
No comments:
Post a Comment