1

LWJGL を使用した Java コードがいくつかあります。

import org.lwjgl.input.Mouse; 
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
...
Display.setDisplayMode(new DisplayMode(200, 200));
Display.create();
Mouse.create();
Mouse.setGrabbed(true);
while (true) 
{
    Display.update();
    System.out.println("Data: d("+ Mouse.getDX() + "," + Mouse.getDY() + ") p(" + Mouse.getX() + "," + Mouse.getY() + ")");
    Thread.sleep(1000/20);
}

マウスを物理的に動かすと問題なく動作しますが、Cocoa アプリケーションを使用してマウスの動きをシミュレートすると、次のようになります。

  • getDX()そしてgetDY()0を返す
  • getX()getY()前の値を返します (マウスが移動していないかのように)

マウスを動かすために使用しているコードは次のとおりです。

PostMouseEvent(0, kCGEventMouseMoved, mouseLocation);
...
void PostMouseEvent(CGMouseButton button, CGEventType type, const CGPoint point)
{    
    CGWarpMouseCursorPosition(point);
    CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, point, button);
    CGEventSetType(theEvent, type);
    CGEventPost(kCGHIDEventTap, theEvent);
    CGAssociateMouseAndMouseCursorPosition(1);
    CFRelease(theEvent);
}

これは、他のほぼすべてのアプリケーション (マウスオーバー イベントを含む) で魅力的に機能します。

LWJGL がマウス イベントに正しく応答するように、Objective-C を変更するにはどうすればよいですか?

乾杯

追加情報:

マウスを物理的に動かして停止した後、(たとえば) ログに次のように表示されます。

Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)

上記は、Cocoa アプリケーションでマウスを動かしたときに引き続き表示されます

次に、マウスをもう一度動かすと、値が次のようにジャンプします。

Data: d(163,123) p(542,-625)     //this seems like a huge change!
Data: d(8,7) p(550,-618)         //normal
Data: d(0,0) p(550,-618)         //normal
Data: d(48,36) p(598,-582)       //etc

マウスがテレポートしたように見えますか?

編集:java.awt.Robotマウスの移動に使用すると、LWJGL は予想どおりに応答します。

4

1 に答える 1

1

によって行われたマウスの動きに応答する Cocoa アプリはないという私の最初の仮定CGEventPostは間違っていました。本当の問題は次のとおりです。

CGEventPostとでマウスを動かした場合、イベントにはと の値CGEventCreateMouseEventがありません。そして、多くのアプリケーションがそれらに依存しているようです (目的のアプリケーション (Minecraft) がそうであるように、LWJGL からこれらの値を受け取ります)。deltaXdeltaY

これらの値を手動で計算し、イベントに設定する必要があります。

私のプロジェクトからのコード例:

CGEventRef pointGetEvent = CGEventCreate(NULL);
CGPoint point = CGEventGetLocation(pointGetEvent);
CFRelease(pointGetEvent);

if(test(SNES_Y)){
    CGPoint oldPoint = point;
    if(test(SNES_LEFT)){
        point = CGPointMake(point.x - MOUSE_STEP, point.y);
    }
    if(test(SNES_RIGHT)){
        point = CGPointMake(point.x + MOUSE_STEP, point.y);
    }
    if(test(SNES_DOWN)){
        point = CGPointMake(point.x, point.y + MOUSE_STEP);
    }
    if(test(SNES_UP)){
        point = CGPointMake(point.x, point.y - MOUSE_STEP);
    }

    if(oldPoint.x != point.x || oldPoint.y != point.y){
        CGEventRef move1 = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, point, kCGMouseButtonLeft);
        CGEventSetDoubleValueField(move1, kCGMouseEventDeltaX, point.x - oldPoint.x);
        CGEventSetDoubleValueField(move1, kCGMouseEventDeltaY, point.y - oldPoint.y);
        CGEventPost(kCGSessionEventTap, move1);
        CFRelease(move1);
    }
}
于 2015-01-26T17:54:54.520 に答える