Создание игр с 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 в вики