Создание игр с JNativeHook

Я работаю над простой программой наложения для компьютерных игр. Это просто прозрачный прямоугольник, расположенный в центре экрана, но его размер контролируется колесиком мыши пользователя. Таким образом, концепция состоит в том, чтобы просто сопоставить размер прозрачного прямоугольника с размером вражеского игрока, чтобы вычислить его расстояние.

К сожалению, я не могу сделать это с обычными слушателями мыши, потому что мышь должна быть одновременно ориентирована на игру и оверлейную программу. Я пробую JNativeHook, но не могу обновить прямоугольник. Любой совет?

public class Main extends Application implements NativeMouseWheelListener {

    Rectangle r = new Rectangle();
    int y = 540; 
    int width = 75;
    int height = 180;
    int velocity = 10;

    @Override
    public void start(Stage stage) throws Exception {
         AnchorPane root = new AnchorPane();
         r = rect(); 
         root.getChildren().add(r);
         root.setStyle("-fx-background-color: rgba(0, 0, 0, 0);");

         Scene scene = new Scene(root, 1920, 1080); 
         scene.setFill(null);

         stage.initStyle(StageStyle.TRANSPARENT);
         stage.setScene(scene);
         stage.setX(0);
         stage.setY(0);
         stage.show();
         stage.setAlwaysOnTop(true);
    }

    public void nativeMouseWheelMoved(NativeMouseWheelEvent e) {
        int direction = e.getWheelRotation();
        System.out.println("Mouse Wheel Moved: " + direction);
        r.setY(r.getY() + direction);
    }

    public Rectangle rect() {
        r.setWidth(width);
        r.setHeight(height);
        r.setX(960 - (width/2));
        r.setY(540);
        r.setFill(Color.TRANSPARENT);
        r.setStroke(Color.BLACK);
        return r;
    }

    public static void main(String[] args) {
        go();
        launch(args);
    }

    public static void go() {
        try {
            GlobalScreen.registerNativeHook();
        }
        catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());
            ex.printStackTrace();
            System.exit(1);
        }

        GlobalScreen.getInstance().addNativeMouseWheelListener(new Main());
    }
}

1 ответ

Я настоятельно рекомендую воспользоваться советом @vince-emigh и запустить JNativeHook в том же потоке, что и ваша среда пользовательского интерфейса, используя пользовательскую реализацию AbstractExecutorService следующим образом.

public class JavaFxDispatchService extends AbstractExecutorService {
    private boolean running = false;

    public JavaFxDispatchService() {
        running = true;
    }

    public void shutdown() {
        running = false;
    }

    public List<Runnable> shutdownNow() {
        running = false;
        return new ArrayList<Runnable>(0);
    }

    public boolean isShutdown() {
        return !running;
    }

    public boolean isTerminated() {
        return !running;
    }

    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
        return true;
    }

    public void execute(Runnable r) {
        Platform.runLater(r);
    }
}

Затем используйте класс в качестве диспетчера событий:

// Set the event dispatcher to a swing safe executor service.
GlobalScreen.setEventDispatcher(new JavaFxDispatchService());

// Initialize native hook.
try {
    GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
    System.err.println("There was a problem registering the native hook.");
    System.err.println(ex.getMessage());
    ex.printStackTrace();
    System.exit(1);
}

GlobalScreen.addNativeKeyListener(this);

Для получения дополнительной информации, пожалуйста, смотрите статью Swing в вики

Другие вопросы по тегам