Обнаружение движения мыши для 3D-мира от первого лица в Java

Я работаю над игрой от первого лица на Java и пытаюсь заставить работать 3D-движение.

Моя проблема в том, что я хотел бы зафиксировать движение мыши, но держать мышь внутри окна. После того, как я зафиксировал движение мыши, я решил, что лучший способ удержать мышь в моем окне — это центрировать мышь в окне после перемещения с помощью Robot.moveMouse(x,y). Это отлично работает, однако движение робота вызывает событие в моем окне, которое затем интерпретируется как обычное событие и, таким образом, перемещает моего персонажа в мире.

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

Есть ли простой способ определить, что движение мыши исходит от робота?

Возможно, есть более простой способ решить мою проблему, которую я упускаю из виду?


person Mike Stone    schedule 14.12.2011    source источник


Ответы (2)


Я решил это, переключившись на NEWT с JOGL 2.0 RC4. В частности, я использую GLWindow и warpPointer вместо фрейма AWT с Robot.mouseMove. С переключателем я мгновенно получил плавные движения. Некоторый пример кода, похожий на то, что я делаю (пробег может отличаться):

public class MyClass implements MouseListener {
    private GLWindow window;
    private int centeredX = -1;
    private int centeredY = -1;

    // ...

    public void mouseMoved(MouseEvent e) {
        if (centeredX == -1 || centeredY == -1) {
            center();
            return;
        }

        int deltaX = e.getX() - centeredX;
        int deltaY = e.getY() - centeredY;

        // ... Do something with the deltas

        centeredX = window.getWidth() / 2;
        centeredY = window.getHeight() / 2;
        window.warpPointer(centeredX, centeredY);
    }
}
person Mike Stone    schedule 16.12.2011

Ну, я не на 100% об этом, но вы использовали функции getsource() или getComponent() в своем событии мыши? Они могут вернуть робота как его источник. За исключением этого, у меня была бы переменная класса, такая как boolean robotControlling, и каждый раз, когда она берет на себя управление мышью, устанавливайте для нее значение true. Затем в вашем mouseListener выполните if(!robotControlling){...}. Надеюсь это поможет.

РЕДАКТИРОВАТЬ: если в вашем приложении есть неиспользуемые кнопки мыши (в Java есть кнопка 1, кнопка 2 и кнопка 3), вы можете заставить робота нажимать ее, а в прослушивателе мыши игнорировать любые события с нажатым кодом. (используйте для этого evt.getButton()) Конечно, это не самое чистое решение: P

person SuperTron    schedule 14.12.2011
comment
Спасибо за ответ! К сожалению, getSource возвращает место, где происходит событие (и я подозреваю, что getComponent аналогичен). Я пытался установить состояние, как вы описываете, но оно не кажется надежным и приводит к странному поведению. Я даже пытался использовать что-то вроде того, что вы описываете, с нажатием кнопок, и это все равно заканчивалось ненадежным поведением. Может быть, я делаю что-то не так с этими подходами, но я, кажется, получаю смешанные события робота и человека, и в итоге я игнорирую события, которых не должен, и наоборот. - person Mike Stone; 14.12.2011
comment
Еще одно замечание: я делаю что-то вроде того, что вы говорите о robotControlling, а затем устанавливаю для него значение false после моего вызова Robot.mouseMove, и внутри события оно всегда ложно (я уверен, что робот не запускает фактическое событие до тех пор, пока не Я отпускаю контроль над потоком или что-то в этом роде) - person Mike Stone; 14.12.2011
comment
Хорошо, а как насчет того, чтобы установить его в значение true, когда вы выполняете mouseMove(), а затем в прослушивателе мыши добавляете if(robotControlling && MOUSE CENTERED)robotControlling = false; Эффективно, обязательно подождите, пока мышь не окажется в центре, прежде чем снимать блокировку? - person SuperTron; 14.12.2011
comment
Это решение, на котором я, наконец, остановился, но оно все еще несовершенно... попробовав его, я обнаружил, что получаю пользовательские события мыши перед центрированными событиями мыши, но перемещаюсь так, как если бы мышь уже была центрирована. Довольно странно ... и кажется, что если я не центрирую после таких случаев, я никогда не получаю фактическое центрированное событие, поэтому я больше не центрируюсь. Возможно, мне придется просто посмотреть на следующее событие и, если оно не в центре, вычислить дельту, как если бы оно уже было в центре, а не в последнем известном месте. - person Mike Stone; 14.12.2011
comment
Примечание. Я говорю, что это несовершенно, потому что проблемы, которые я описал в своем последнем комментарии, заставили движение выглядеть отрывистым и неестественным, так что это плохое решение, хотя и несколько функциональное. - person Mike Stone; 14.12.2011
comment
Ну, вы также можете начать учитывать направление движений мыши, независимо от того, направлены ли они к центру или нет, и т. д. К сожалению, в java нет простого способа различать события (насколько я могу судить.) - person SuperTron; 14.12.2011