Exemple de gestion des entrées d'une manette avec LWJGL (Lightweight Java Game Library)

Maven LWJGL

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>fr.ronanlefichant</groupId>
	<artifactId>controllerlwjgl</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<lwjgl.version>3.3.2</lwjgl.version>
		<lwjgl.natives>natives-windows</lwjgl.natives>
	</properties>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.lwjgl</groupId>
				<artifactId>lwjgl-bom</artifactId>
				<version>${lwjgl.version}</version>
				<scope>import</scope>
				<type>pom</type>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.openjfx</groupId>
			<artifactId>javafx-controls</artifactId>
			<version>18.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-assimp</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-bgfx</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-cuda</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-egl</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-fmod</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-freetype</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-glfw</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-harfbuzz</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-hwloc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-jawt</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-jemalloc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-ktx</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-libdivide</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-llvm</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-lmdb</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-lz4</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-meow</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-meshoptimizer</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-nanovg</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-nfd</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-nuklear</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-odbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-openal</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-opencl</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-opengl</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-opengles</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-openvr</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-openxr</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-opus</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-ovr</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-par</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-remotery</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-rpmalloc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-shaderc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-spvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-sse</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-stb</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-tinyexr</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-tinyfd</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-tootle</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-vma</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-vulkan</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-xxhash</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-yoga</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-zstd</artifactId>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-assimp</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-bgfx</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-freetype</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-glfw</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-harfbuzz</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-hwloc</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-jemalloc</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-ktx</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-libdivide</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-llvm</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-lmdb</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-lz4</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-meow</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-meshoptimizer</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-nanovg</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-nfd</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-nuklear</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-openal</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-opengl</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-opengles</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-openvr</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-openxr</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-opus</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-ovr</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-par</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-remotery</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-rpmalloc</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-shaderc</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-spvc</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-sse</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-stb</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-tinyexr</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-tinyfd</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-tootle</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-vma</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-xxhash</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-yoga</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
		<dependency>
			<groupId>org.lwjgl</groupId>
			<artifactId>lwjgl-zstd</artifactId>
			<classifier>${lwjgl.natives}</classifier>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.0</version>
				<configuration>
					<release>11</release>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.openjfx</groupId>
				<artifactId>javafx-maven-plugin</artifactId>
				<version>0.0.6</version>
				<executions>
					<execution>
						<!-- Default configuration for running -->
						<!-- Usage: mvn clean javafx:run -->
						<id>default-cli</id>
						<configuration>
							<mainClass>fr.ronanlefichant.controllerlwjgl.ControllerApp</mainClass>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

API LWJGL

package fr.ronanlefichant.controllerlwjgl;

import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_X;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_BUTTON_A;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_BUTTON_X;
import static org.lwjgl.glfw.GLFW.GLFW_JOYSTICK_1;
import static org.lwjgl.glfw.GLFW.glfwGetGamepadState;
import static org.lwjgl.glfw.GLFW.glfwGetJoystickName;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwJoystickIsGamepad;

import java.io.IOException;

import org.lwjgl.glfw.GLFWGamepadState;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ControllerApp extends Application {

  @Override
  public void start(Stage stage) {

    // Création de la tâche de fond
    Task < Void > txtAreaRefreshTask = new Task < Void > () {
      @Override
      public Void call() throws InterruptedException {
        // Initialisation de glfw
        glfwInit();

        // Si la manette est un gamepad
        boolean isGamepad = glfwJoystickIsGamepad(GLFW_JOYSTICK_1);
        if (isGamepad) {
          System.out.println("Une manette est présente");

          // Récupération du nom
          String joystickName = glfwGetJoystickName(GLFW_JOYSTICK_1);
          System.out.println(joystickName);

          while (true) {
            // Création de l'état
            GLFWGamepadState state = GLFWGamepadState.create();
            // Récupération de l'état
            glfwGetGamepadState(GLFW_JOYSTICK_1, state);

            // Récupération des états des boutons, axes et gachettes de la manette
            String rightAxisValue = state.axes(GLFW_GAMEPAD_AXIS_RIGHT_X) + " , " +
              state.axes(GLFW_GAMEPAD_AXIS_RIGHT_Y);
            String leftAxisValue = state.axes(GLFW_GAMEPAD_AXIS_LEFT_X) + " , " +
              state.axes(GLFW_GAMEPAD_AXIS_LEFT_Y);
            String stateButtonA = state.buttons(GLFW_GAMEPAD_BUTTON_A) == 1 ? "PRESSED" : "RELEASED";
            String stateButtonX = state.buttons(GLFW_GAMEPAD_BUTTON_X) == 1 ? "PRESSED" : "RELEASED";
            String leftTriggerValue = "Gachette gauche : " + state.axes(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER);
            String rightTriggerValue = "Gachette droite : " + state.axes(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER);

            updateMessage("Etat du bouton A : " + stateButtonA + "\nEtat du bouton X : " + stateButtonX +
              "\nAxe gauche : " + leftAxisValue + "\nAxe droit : " + rightAxisValue + "\n" +
              leftTriggerValue + "\n" + rightTriggerValue);
          }

        }
        return null;
      }
    };

    // La zone texte qui affiche les états du joystick
    TextArea textArea = new TextArea();
    textArea.setEditable(false);
    textArea.textProperty().bind(txtAreaRefreshTask.messageProperty());
    var root = new StackPane(textArea);

    // Création du Thread et démarrage
    Thread refreshThread = new Thread(txtAreaRefreshTask);
    // Le thread sera coupé lorsque l'application est fermée
    refreshThread.setDaemon(true);
    refreshThread.start();

    Scene scene = new Scene(root, 300, 120);
    stage.setScene(scene);
    stage.show();
  }

  public static void main(String[] args) throws InterruptedException, IOException {
    launch();
  }

}

Commentaires