Hello,
I launched the TestJosticks test from JME tests, but I receive the message :
java.lang.IllegalStateException: Cannot find any joysticks!
I tested on Windows 10 and Linux.
For info, my gamepaf works with libGDX.
Do you have any idea ?
Did you enable the use of Joysticks?
public static void main(String[] args) {
AppSettings settings = new AppSettings(true);
settings.setUseJoysticks(true);
Main app = new Main();
app.setSettings(settings);
app.start();
// More code
}
What happens when you print the names of the joysticks?
Joystick[] joysticks = inputManager.getJoysticks();
for(Joystick jst: joysticks){
System.out.println(jst.getName());
}
Which does tend to enable the joysticks:
ā¦presuming something didnāt go wrong in launch.
TestJoysticks also dumps the joysticks.
I donāt have any specific help for you but I do feel like a similar question may have been asked here in the past.
I know people have managed to get some XBOX controllers working in JME because there have been other config tweaks, etc. related to that over the years.
In that light, if you do not find a better answer by searching the forum, it might be useful to know more specifics about which version of JME you are running, which version of JMEās lwjgl support you have enabled, etcā¦ and perhaps some more specifics about the controller you use. (I donāt knowā¦ I guess there are differences in xbox controllers.)
welcome @takyon to JME!!
I want to ask a few quetions so we can help you with your issue
- is your project using jme3-lwjgl3 or jme3-lwjgl?
- Is your Xbox controller connected via USB of Wireless?
- Do game clients like Steam recognize your gamepad? Note: this may be a stupid question but I never hooked up a gamepad to my PC before developing Depthris and I had some issues detecting it with JME
Thanks [bloodwalker],
to answer yout questions :
I have this line in my gradle file :
implementation āorg.jmonkeyengine:jme3-lwjgl3:$jmeVerā
So I think I use jme3-lwjgl3.
I connect my controller via USB
Yes, I play with it to Steam or Epic games.
And as I said, it is recognized by libGDX.
I recently decided to port my game from libGDX to JME, so I have this gradle script
project.ext {
jmeVer = '3.6.1-stable'
}
project(":assets") {
apply plugin: "java"
buildDir = rootProject.file("build/assets")
sourceSets {
main {
resources {
srcDir '.'
}
}
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
}
dependencies {
// Core JME
implementation "org.jmonkeyengine:jme3-core:$jmeVer"
implementation "org.jmonkeyengine:jme3-desktop:$jmeVer"
// Mac OS with LWJGL 3 doesn't allow AWT/Swing
if (!System.getProperty("os.name").toLowerCase().contains("mac")) {
implementation "org.jmonkeyengine:jme3-awt-dialogs:$jmeVer"
}
implementation "org.jmonkeyengine:jme3-lwjgl3:$jmeVer"
// Suppress errors / warnings building in SDK
implementation "org.jmonkeyengine:jme3-jogg:$jmeVer"
implementation "org.jmonkeyengine:jme3-plugins:$jmeVer"
// GUI Library
implementation "com.simsilica:lemur:1.16.0"
// Physics Library
implementation "com.github.stephengold:Minie:8.0.0"
// Networking Library
implementation "com.github.tlf30:monkey-netty:0.1.1"
// Additional Libraries
implementation "org.jmonkeyengine:jme3-effects:$jmeVer"
implementation "org.jmonkeyengine:jme3-terrain:$jmeVer"
implementation "org.jmonkeyengine:jme3-testdata:$jmeVer"
implementation "com.github.stephengold:Heart:9.0.0"
implementation "com.epagagames:particlemonkey:1.1.0"
implementation "com.github.polincdev:ShaderBlowEx:-SNAPSHOT"
implementation "com.simsilica:sio2:1.8.0"
implementation "com.simsilica:zay-es:1.5.0"
implementation "com.simsilica:zay-es-net:1.5.2"
// Assets sub-project
runtimeOnly project(':assets')
}
jar {
manifest {
attributes 'Main-Class': application.mainClass
}
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
wrapper {
gradleVersion = '8.4'
}
[Pixelapp]as [pspeed] said, I tested TestJoysticks, which enables joysticks
settings.setUseJoysticks(true);
Thanks for your help
Ok, Looking at your gradle file it should be detected.
I modified the TestJoysticks code to try something else. The original code will throw an exception if no joysticks are connected when the app starts. I added a code to detect when it is connected after starting. so we can see if you get anything when you plug in your gamepad after the app starts.
package org.blocks;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.*;
import com.jme3.input.event.JoyAxisEvent;
import com.jme3.input.event.JoyButtonEvent;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import com.jme3.scene.Node;
import com.jme3.system.AppSettings;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
public class TestJoystickSimplified extends SimpleApplication {
private Joystick viewedJoystick;
private Node joystickInfo;
private float yInfo = 0;
public static void main(String[] args){
TestJoystickSimplified app = new TestJoystickSimplified();
AppSettings settings = new AppSettings(true);
settings.setUseJoysticks(true);
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
getFlyByCamera().setEnabled(false);
inputManager.addJoystickConnectionListener(connectionListener);
// If there are no Joysticks connected when the application starts it will just print a message.
Joystick[] joysticks = inputManager.getJoysticks();
if (joysticks == null)
System.out.println("Cannot find any joysticks!");
try {
PrintWriter out = new PrintWriter( new FileWriter( "joysticks-" + System.currentTimeMillis() + ".txt" ) );
dumpJoysticks( joysticks, out );
out.close();
} catch( IOException e ) {
throw new RuntimeException( "Error writing joystick dump", e );
}
joystickInfo = new Node( "joystickInfo" );
joystickInfo.setLocalTranslation( 0, cam.getHeight(), 0 );
guiNode.attachChild( joystickInfo );
// Add a raw listener because it's easier to get all joystick events
// this way.
inputManager.addRawInputListener( new JoystickEventListener() );
}
protected void dumpJoysticks( Joystick[] joysticks, PrintWriter out ) {
for( Joystick j : joysticks ) {
dumpJoystick(j, out);
}
}
protected void dumpJoystick( Joystick j, PrintWriter out ) {
out.println( "Joystick[" + j.getJoyId() + "]:" + j.getName() );
out.println( " buttons:" + j.getButtonCount() );
for( JoystickButton b : j.getButtons() ) {
out.println( " " + b );
}
out.println( " axes:" + j.getAxisCount() );
for( JoystickAxis axis : j.getAxes() ) {
out.println( " " + axis );
}
}
protected void addInfo( String info, int column ) {
BitmapText t = new BitmapText(guiFont);
t.setText( info );
t.setLocalTranslation( column * 200, yInfo, 0 );
joystickInfo.attachChild(t);
yInfo -= t.getHeight();
}
protected void setViewedJoystick( Joystick stick ) {
if( this.viewedJoystick == stick )
return;
if( this.viewedJoystick != null ) {
joystickInfo.detachAllChildren();
}
this.viewedJoystick = stick;
if( this.viewedJoystick != null ) {
// Draw the hud
yInfo = 0;
addInfo( "Joystick:\"" + stick.getName() + "\" id:" + stick.getJoyId(), 0 );
yInfo -= 5;
float ySave = yInfo;
// Column one for the buttons
addInfo( "Buttons:", 0 );
for( JoystickButton b : stick.getButtons() ) {
addInfo( " '" + b.getName() + "' id:'" + b.getLogicalId() + "'", 0 );
}
yInfo = ySave;
// Column two for the axes
addInfo( "Axes:", 1 );
for( JoystickAxis a : stick.getAxes() ) {
addInfo( " '" + a.getName() + "' id:'" + a.getLogicalId() + "' analog:" + a.isAnalog(), 1 );
}
}
}
/**
* Listener when a joystick connects/disconnects
*/
private JoystickConnectionListener connectionListener = new JoystickConnectionListener() {
@Override
public void onConnected(Joystick joystick) {
System.out.println("Joystick connected: " + joystick.getName());
try {
PrintWriter out = new PrintWriter( new FileWriter( "joysticks-" + System.currentTimeMillis() + ".txt" ) );
dumpJoystick(joystick, out);
} catch (IOException e) {
throw new RuntimeException( "Error writing joystick dump", e );
}
}
@Override
public void onDisconnected(Joystick joystick) {
System.out.println("Joystick disconnected: " + joystick.getName());
}
};
/**
* Easier to watch for all button and axis events with a raw input listener.
*/
protected class JoystickEventListener implements RawInputListener {
final private Map<JoystickAxis, Float> lastValues = new HashMap<>();
@Override
public void onJoyAxisEvent(JoyAxisEvent evt) {
Float last = lastValues.remove(evt.getAxis());
float value = evt.getValue();
// Check the axis dead zone. InputManager normally does this
// by default but not for raw events like we get here.
float effectiveDeadZone = Math.max(inputManager.getAxisDeadZone(), evt.getAxis().getDeadZone());
if( Math.abs(value) < effectiveDeadZone ) {
if( last == null ) {
// Just skip the event
return;
}
// Else set the value to 0
lastValues.remove(evt.getAxis());
value = 0;
}
setViewedJoystick( evt.getAxis().getJoystick() );
//gamepad.setAxisValue( evt.getAxis(), value );
if( value != 0 ) {
lastValues.put(evt.getAxis(), value);
}
}
@Override
public void onJoyButtonEvent(JoyButtonEvent evt) {
setViewedJoystick( evt.getButton().getJoystick());
if(evt.isPressed()) {
System.out.println(evt.getButton().getButtonId());
}
}
@Override
public void beginInput() {}
@Override
public void endInput() {}
@Override
public void onMouseMotionEvent(MouseMotionEvent evt) {}
@Override
public void onMouseButtonEvent(MouseButtonEvent evt) {}
@Override
public void onKeyEvent(KeyInputEvent evt) {}
@Override
public void onTouchEvent(TouchEvent evt) {}
}
}
Hello, sorry for late answer, I didnāt have much time to work on my project.
I donāt know what happened, but now, my controller works in Linux.
Now, Iām several several problems, but letās begin with this one :
When I implement RawInputListener, and the method public void
onJoyAxisEvent(JoyAxisEvent evt) {
the call to evt.getJoyIndex() returns two different indexes, while I have only one controller plugged. Is the keyboard considered as a joystick some way ?
Hi, little up of my question ^^
Some āeventā happened. If it were me, Iād dump all of the information about the event and notice what I was doing when the event happened.
Your joystick likely has several axes. Left/right for both sticks. Up/down for both sticks. Usually at least one axis (sometimes two) for the bottom triggers.
Edit: and yes, while Iād expect all joystick events from the same joystick to have the same ājoyIndexā, itās not necessarily true. You also may have some other device with an axis on it.
ā¦something on the event may provide more information since there are also ālogical IDsā for things.
Ok, there were actualy my laptop keyboard having axis.
To detect only real josticks, i use this code
Joystick playerJoystick = null;
Joystick[] joysticks = getInputManager().getJoysticks();
if (joysticks != null) {
for (Joystick joystick : joysticks) {
if (joystick.getAxes().size() > 2) {
playerJoystick = joystick;
}
}
player = new Player(inputListener = new JoystickAndKeyboardEventListener(playerJoystick,
getInputManager().getAxisDeadZone()), character);
getInputManager().addRawInputListener(inputListener);
}