0

I am writing a Java video game which works well with the keyboard. I want to also add joystick support and found the convenient class JInput.

However (apparently) unlike keyboard input which automatically fires an event, gaining input from a joystick/gamepad requires constant checking for button pressed events.

Because of this I have written the following timer task which searches every 50 milleseconds for input:

    Joystick_Input_Thread.schedule(new TimerTask() {
        @Override
        public void run() { 

            // If at least one controller was found we start firing action for the keys.
            try {
                if(!foundControllers.isEmpty()) {

                    clearControllerData(activeAction);
                    getControllerData(activeAction);

                }
            } catch (Exception e) {
                // Hmm.. crash due to initialization error probably
                System.out.println("JOYSTICK THREAD INITIALIZATION ERROR");
                this.cancel();
            }

        }
    }, 0, 50);

However, as is expected this class slows down the game somewhat. I don't really want to decrease the frequency I run this class because 50 milliseconds is a little slow registering input anyway for my fast-action game.

The issue real issue is the weight of the getControllerData() method. Because of the way the JInput has been designed (unless I have misunderstood something) you have to iterate through every button on the controller and check each one.

It looks something like this:

// go through all components of the controller.
Component[] components = selectedController.getComponents();


// iterate through all the controls
for(Component c : components) {

    Component.Identifier componentIdentifier = c.getIdentifier();

    // check if the component is a BUTTON
    if(componentIdentifier.getName().matches("^[0-9]*$")) { 
       // check if it is pressed
       // ...
    } 

    // check if the component is a HAT SWITCH
    else if (componentIdentifier == Component.Identifier.Axis.POV) {
       // check if it has moved
       // ...
    }

    // check if the component is an AXES
    else if (component.isAnalog()) {
       // check if it has been activated
       // ...
    }

    // act on that...
}

Its incredibly verbose because for each component on the joystick/gamepad I have to A) figure out what it is, B) figure out if it has been pressed, and finally C) fire the action event.

So my questions are: overall, how can I improve the overall performance of the jostick input?

Is there a simpler way to figure out if a button has been pressed (rather than analyzing the component to figure out what type it is and then checking if it has been pressed)?

I see the key weakness in the frequent iteration. What is a reasonable refresh rate for checking for input? Is there a way to receive jinput without all the loops?

Lastly, are there any other 3rd party Java classes that are better designed to handle this input?

FatFrank
  • 73
  • 1
  • 10
  • Honestly, the biggest performance hit is probably the `matches` method. You should use `if (componentIdentifier instanceof Component.Identifier.Button)` instead. Looping through a handful of components will take a negligible amount of time. As for frequency, I personally find that ten times per second is plenty. – VGR Jan 10 '20 at 16:01
  • Thanks for your comments! I will definitely make both of those changes! – FatFrank Jan 10 '20 at 21:01
  • @VGR - Unfortunately the `instanceof` does not work for all the buttons? (on certain controllers some of the buttons don't register) – FatFrank Jan 11 '20 at 05:33

0 Answers0