1

About: I have a panel displaying a map that is constructed out of polygons and lines. To this map I apply transformations and provide a way to walk around (first-person-like) with rotating and moving the map with transformations.

The transformations applied to the map seem to block (or atleast slowdown) KeyEvents from beeing handled. Sometimes the application keeps rotating even if I released the key.

Also I noticed that the rotation transformation has a bigger impact on this effect.

The collision-detection has no effect on this (since its disabled at this point).

Due to the structure of the application I bind centerR to pointerR.

centerR.bind(pointerR);

Transformations applied:

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-Setup:

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 回答