3
\$\begingroup\$

I am trying to map multiple input types to single in-game controls using libGDX's InputProcessor and ControllerListener interfaces. Currently, I have created a single InputType interface which is inherited by the following enumerations:

  • Keys
  • MouseButtons
  • Buttons (Gamepad)
  • Axis (Gamepad)

The InputType interface declares a single method getCode(); as all inheriting enumerations have their own codes.

I have created a Keyboard class which implements InputProcessor and a Gamepad class which implements ControllerListener. Both classes extend from a generic InputHandler class which stores a Set<T extends InputType>. I also created a Mouse class and AxisHandler class which work similarly, although as touch events are handled within the InputProcessor and axis events handled within the ControllerListener, the Keyboard and Gamepad classes contain instances of these classes respectively.

Finally, to map multiple input types to single controls, I created a ControlMap class which stores an EnumMap<Controls, InputType[]>, where Controls is an enumeration containing all controls that are present within the game (MOVE_UP, MOVE_DOWN, ATTACK, etc.)

The obvious problem with this is that I'm going from an event-driven approach to polling. Every time input is processed, I'm storing the associated InputType accordingly, and this can create an overhead after some time.

My game uses a component-based architecture, so in my MovementSystem I'd check whether controls are down by using if (Controls.controlDown(Controls.MOVE_DOWN)). I can't seem to find any other way of approaching this problem just yet. There is no apparent drop in performance; when input isn't being handled, nothing is stored. Is my method fine as it is and am I over thinking the problem too much?

My UML is terrible but here's how I can best describe the process:

Input Handling UML

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

    If the library you use only has polling for input then you will have to use polling there are no secrets.

    To solve the issue of polling in a component system you can create an input system which will only check the status of the input sources your input components have subscribed to.

    This way your components are all updated at the same time (and they are free to process the changes or lack of) the way they want after the polling of all inputs have ended.

    Then you can have Intent Components which can process the change events sent from the Input components and process the complex scenarios where multiple inputs change within a timeframe or in particular conditions have to be handled independently from the controller type or other constraints.

    \$\endgroup\$

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