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?