1

概要: 多角形と線で構成されたマップを表示するパネルがあります。このマップに変換を適用し、変換を使用してマップを回転および移動させて (一人称のように) 歩き回る方法を提供します。

マップに適用された変換は、KeyEvents の処理を​​ブロック (または少なくともスローダウン) しているようです。キーを離しても、アプリケーションが回転し続けることがあります。

また、回転変換がこの効果に大きな影響を与えることに気付きました。

衝突検出はこれには影響しません (この時点で無効になっているため)。

アプリケーションの構造により、centerR を pointerR にバインドします。

centerR.bind(pointerR);

適用された変換:

mapElements = new Group();

Scale s = new Scale();
s.xProperty().bind(zoom);
s.yProperty().bind(zoom);
s.setPivotX(panelBounds.getWidth() / 2);
s.setPivotY(panelBounds.getHeight() / 2);

mapElements.getTransforms().add(s);

Translate t = new Translate();
t.xProperty().bind(new SimpleDoubleProperty(panelBounds.getWidth() / 2).subtract(centerX));
t.yProperty().bind(new SimpleDoubleProperty(panelBounds.getHeight() / 2).subtract(centerY));

mapElements.getTransforms().add(t);

Rotate r = new Rotate();
r.angleProperty().bind(centerR.multiply(-1));
r.pivotXProperty().bind(centerX);
r.pivotYProperty().bind(centerY);

mapElements.getTransforms().add(r);

KeyListener-セットアップ:

setOnKeyPressed(new EventHandler<KeyEvent>()
{
    @Override
    public void handle(KeyEvent event)
    {
        System.out.println(event);
        if (event.getCode() == KeyCode.UP)
            moveForwards = true;
        if (event.getCode() == KeyCode.DOWN)
            moveBackwards = true;
        if (event.getCode() == KeyCode.LEFT)
            rotateLeft = true;
        if (event.getCode() == KeyCode.RIGHT)
            rotateRight = true;
    }
});
setOnKeyReleased(new EventHandler<KeyEvent>()
{
    @Override
    public void handle(KeyEvent event)
    {
        System.out.println(event);
        if (event.getCode() == KeyCode.UP)
            moveForwards = false;
        if (event.getCode() == KeyCode.DOWN)
            moveBackwards = false;
        if (event.getCode() == KeyCode.LEFT)
            rotateLeft = false;
        if (event.getCode() == KeyCode.RIGHT)
            rotateRight = false;
    }
});

OnFrame-Rotation:

private final double    fps     = 20;
private final KeyFrame  frame   = new KeyFrame(Duration.millis(1000 / fps), new EventHandler<ActionEvent>()

{
@Override
public void handle(ActionEvent event)
    {
        double movement = ((moveForwards ? 3 : 0) 
                        + (moveBackwards ? -3 : 0))
                        * movementSpeed;

        double rotation = ((rotateLeft ? -3 : 0) 
                        + (rotateRight ? 3 : 0))
                        * rotateSpeed;

        double oldX = pointerX.get();
        double oldY = pointerY.get(); 

        pointerX.set(pointerX.get() 
                    + Math.cos((pointerR.get() - 90) * Math.PI / 180) 
                    * movement);

        pointerY.set(pointerY.get()
                + Math.sin((pointerR.get() - 90) * Math.PI / 180) 
                    * movement);

        if (checkCollisions)
            handleCollision(oldX, oldY, pointerX.get(), pointerY.get());
        pointerR.set(pointerR.get() + rotation);
    }
});
4

1 に答える 1

0

setOnKeyPressed でどのノードを呼び出していますか? このメソッドの javadoc を見ると、次のようになります。

Defines a function to be called when this Node or its child Node 
has input focus and a key has been pressed. The function is called 
only if the event hasn't been already consumed during its capturing
or bubbling phase.

リスナーがシーンに追加されていない場合は、リスナーが追加されていることを確認し、イベント オブジェクトで消費メソッドを呼び出すものがないことを確認します。

于 2012-11-05T12:21:11.693 に答える