Javaでジョイスティックの入力を受け取る方法はJInputなるライブラリでもできるのだが、
ネイティブライブラリ(DLL)をパスの通った場所に置かなくてはならないとか、
どうもMac/Linuxはなさそうとかで、色々嫌だったのでLWJGLなるライブラリを使ってみる。
まずLWJGL3を https://www.lwjgl.org/ から適当にダウンロードしてくる。
必要なjarはwindowsの場合は下記4つ。
- lwjgl.jar
- lwjgl-natives-windows.jar
- lwjgl-glfw.jar
- lwjgl-glfw-natives-windows.jar
Mac/Linuxはnatives-macとかnatives-linuxとかを使えばいけると思う
こんなコードで実験した。
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import org.lwjgl.glfw.GLFW;
public class JoyStick {
public static void main(String[] args) {
// GLFWを初期化します。これを行わないとほとんどのGLFW関数は機能しない。
if(!GLFW.glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
GLFW.glfwPollEvents();
int stick;
for(stick = 0; stick <= GLFW.GLFW_JOYSTICK_LAST; stick++) {
if(!GLFW.glfwJoystickPresent(stick)) continue;
System.out.println("JoyStick(" + stick + ")Name:" +
GLFW.glfwGetJoystickName(stick) + " " +
GLFW.glfwGetGamepadName(stick));
break;
}
if(stick > GLFW.GLFW_JOYSTICK_LAST) return;
for(int i = 0; i < 1000; i++) {
int count1 = 0;
FloatBuffer floatBuffer = GLFW.glfwGetJoystickAxes(stick);
System.out.print("Axes:");
while (floatBuffer.hasRemaining()) {
float axes = floatBuffer.get();
System.out.print(count1 + "," + axes + " ");
count1++;
}
int count2 = 0;
System.out.print("Button:");
ByteBuffer byteBuffer = GLFW.glfwGetJoystickButtons(stick);
while (byteBuffer.hasRemaining()) {
byte button = byteBuffer.get();
System.out.print(count2 + "," + button + " ");
count2++;
}
System.out.println();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
実行結果はこんな風になるはず。
JoyStick(0)Name:PC Game Controller SVEN X-PAD
Axes:0,1.5259022E-5 1,1.5259022E-5 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,1.5259022E-5 1,1.5259022E-5 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,-0.3515526 1,1.5259022E-5 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,-1.0 1,-0.20311284 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,-1.0 1,-0.17967498 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,-1.0 1,1.5259022E-5 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,-1.0 1,1.5259022E-5 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,-1.0 1,1.0 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
Axes:0,1.5259022E-5 1,1.0 2,1.5259022E-5 3,1.5259022E-5 4,1.5259022E-5 Button:0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,0 15,0
ジョイスティックは無駄に16本まで使える。ここでは最初の1本しか対象にしてない。
glfwGetJoystickAxes()で取得できるfloatバッファの一つ目が左側スティックのX座標、二つ目がY座標となっている。Axesは5つバッファがあるが右側スティックと他にもう一軸。なんだこれ???
アナログだろうがデジタルだろうが、スティックのセンターが0.0ではない。絶対値で0.01以下は切り捨てとかしないと0.0は取れない模様。
glfwGetJoystickButtons()で取得できるbyteバッファは素直にボタン番号順のようだ。Buttonsも16個もバッファがあるが使うのは最初の数個だけだろう。
はまりどころはglfwInit()。これやらなくて動かなかった。
てかInitで失敗ってなんだよ。。。
LWJGLの作法だと、import static org.lwjgl.glfw.GLFW.*;
とかしなきゃならないらしいが、Javaっぽくないのでフツーにインポートして使ってる。
あとは煮るなり焼くなりご自由に。