调用dispatchKeyEvent来执行形状转换

时间:2017-03-22 09:31:46

标签: java javafx timer keyboard-events

我正在使用JavaFX开发一个简单的Pong克隆,我很难移动桨。我想为此使用KeyEventDispatcher,并在AnimationTimer循环期间检查按键操作。

我的Main课程:

public class Main extends Application {

    private Player m_pUser;

    @Override
    public void start(Stage primaryStage) throws Exception{

        Group root = new Group();
        Scene scene = new Scene(root, 500, 300);
        ObservableList list = root.getChildren();

        KeyPressedChecker kpc = new KeyPressedChecker();

        m_pUser = new Player(kpc);

        list.add(m_pUser.getPaddleDrawable());

        GamePlayLoop gameLoop = new GamePlayLoop(m_pUser);
        gameLoop.start();

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

我的GamePlayLoop课程:

public class GamePlayLoop extends AnimationTimer {

    Player m_pUser;

    public GamePlayLoop(Player p) {
        m_pUser = p;
    }

    public void handle(long now) {
        m_pUser.update();
    }
}

我的KeyPressedChecker课程:

public class KeyPressedChecker implements KeyEventDispatcher {

    private static boolean downPressed = false;

    @Override
    public boolean dispatchKeyEvent(KeyEvent ke) {
        synchronized (KeyPressedChecker.class) {
            switch (ke.getID()) {

                case KeyEvent.KEY_PRESSED:
                    if (ke.getKeyCode() == KeyEvent.VK_DOWN)
                        downPressed = true;
                break;
                case KeyEvent.KEY_RELEASED:
                    if (ke.getKeyCode() == KeyEvent.VK_DOWN)
                        downPressed = false;
                    break;
            }

            return false;
        }
    }

    public static boolean isDownPressed() {
        synchronized (KeyPressedChecker.class) {
            return downPressed;
        }
    }
}

我的Player课程:

public class Player {

    private Paddle m_paddle;
    private KeyPressedChecker m_kpc;

    public Player(KeyPressedChecker kpc) {
        m_paddle = new Paddle();
    }

    public Rectangle getPaddleDrawable() {
        return m_paddle.getDrawable();
    }

    public void update() {
        if (m_kpc.isDownPressed())
            m_paddle.moveDown();
        m_paddle.update();
    }
}

最后我的Paddle课程:

public class Paddle {

    private Rectangle m_rect;
    private double m_nPosY;

    public Paddle() {
        m_rect = new Rectangle(10, 60);
    }

    public void moveDown() {
        m_nPosY += 5;
    }

    public Rectangle getDrawable() {
        return m_rect;
    }

    public void update() {
        m_rect.setTranslateY(m_nPosY);
    }
}

我的问题是拍子不会在场景中翻译。实际上,dispatchKeyEvent根本没有被调用。这是为什么?

1 个答案:

答案 0 :(得分:0)

KeyEventDispatcher是AWT的一部分,AWT是一个完全独立于JavaFX的工具包。 (即使它是JavaFX的一部分,你只是实例化你的实现类,但从不对它做任何事情......)。

在JavaFX中执行此操作的方法是为场景注册KeyEvent.KEY_PRESSED事件的事件处理程序。

所以使用你当前的设计(大约)你会做

public class KeyPressedChecker implements EventHandler<KeyEvent> {

    private boolean downPressed = false;

    @Override
    public void handle(KeyEvent ke) {
        if (ke.getEventType() == KeyEvent.KEY_PRESSED) {
            downPressed = true ;
        } else if (ke.getEventType() == KeyEvent.KEY_RELEASED) {
            downPressed = false ;
        }   
    }

    public boolean isDownPressed() {
        return downPressed;
    }

}

Player课程中(我重命名的字段与正确的naming conventions匹配)

public class Player {

    private Paddle paddle;
    private KeyPressedChecker kpc;

    public Player(KeyPressedChecker kpc) {
        this.paddle = new Paddle();
        this.kpc = kpc ;
    }

    public Rectangle getPaddleDrawable() {
        return paddle.getDrawable();
    }

    public void update() {
        if (kpc.isDownPressed())
            paddle.moveDown();
        paddle.update();
    }
}

然后所有内容都与

链接在一起
public class Main extends Application {

    private Player pUser;

    @Override
    public void start(Stage primaryStage) throws Exception{

        Group root = new Group();
        Scene scene = new Scene(root, 500, 300);
        ObservableList list = root.getChildren();

        KeyPressedChecker kpc = new KeyPressedChecker();

        scene.addEventHandler(KeyEvent.ANY, kpc);

        pUser = new Player(kpc);

        list.add(pUser.getPaddleDrawable());

        GamePlayLoop gameLoop = new GamePlayLoop(pUser);
        gameLoop.start();

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}