调用 dispatchKeyEvent 进行形状转换

Call dispatchKeyEvent to perform shape translation

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

我的 Main class:

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);
    }
}

我的GamePlayLoopclass:

public class GamePlayLoop extends AnimationTimer {

    Player m_pUser;

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

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

我的 KeyPressedChecker class:

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;
        }
    }
}

我的Playerclass:

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

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 根本没有被调用。这是为什么?

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

在 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 class 中(我重命名了字段以匹配正确的 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);
    }
}