如何为JavaFX编写KeyListener

时间:2015-04-30 08:11:04

标签: javafx java-8 actionlistener keylistener

我想写一个小游戏,我可以使用 W A S ,在JavaFX Panel上移动球。 kbd> D 键。
我有getPosX()setPosX(),但我不知道如何撰写KeyListener,例如如果按 D ,则计算setPosX(getPosX()+1)

我该怎么做?

3 个答案:

答案 0 :(得分:17)

来自JavaRanch Forum post

在场景中添加按键和释放处理程序,并更新应用程序中记录的移动状态变量。动画计时器挂钩到JavaFX脉冲机制(默认情况下将被限制为每秒发射60次事件) - 这是一种游戏“循环”。在计时器中,检查运动状态变量并将其delta动作应用于角色位置 - 这实际上会使角色围绕屏幕移动以响应按键。

zelda

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * Hold down an arrow key to have your hero move around the screen.
 * Hold down the shift key to have the hero run.
 */
public class Runner extends Application {

    private static final double W = 600, H = 400;

    private static final String HERO_IMAGE_LOC =
            "http://icons.iconarchive.com/icons/raindropmemory/legendora/64/Hero-icon.png";

    private Image heroImage;
    private Node  hero;

    boolean running, goNorth, goSouth, goEast, goWest;

    @Override
    public void start(Stage stage) throws Exception {
        heroImage = new Image(HERO_IMAGE_LOC);
        hero = new ImageView(heroImage);

        Group dungeon = new Group(hero);

        moveHeroTo(W / 2, H / 2);

        Scene scene = new Scene(dungeon, W, H, Color.FORESTGREEN);

        scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                switch (event.getCode()) {
                    case UP:    goNorth = true; break;
                    case DOWN:  goSouth = true; break;
                    case LEFT:  goWest  = true; break;
                    case RIGHT: goEast  = true; break;
                    case SHIFT: running = true; break;
                }
            }
        });

        scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                switch (event.getCode()) {
                    case UP:    goNorth = false; break;
                    case DOWN:  goSouth = false; break;
                    case LEFT:  goWest  = false; break;
                    case RIGHT: goEast  = false; break;
                    case SHIFT: running = false; break;
                }
            }
        });

        stage.setScene(scene);
        stage.show();

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                int dx = 0, dy = 0;

                if (goNorth) dy -= 1;
                if (goSouth) dy += 1;
                if (goEast)  dx += 1;
                if (goWest)  dx -= 1;
                if (running) { dx *= 3; dy *= 3; }

                moveHeroBy(dx, dy);
            }
        };
        timer.start();
    }

    private void moveHeroBy(int dx, int dy) {
        if (dx == 0 && dy == 0) return;

        final double cx = hero.getBoundsInLocal().getWidth()  / 2;
        final double cy = hero.getBoundsInLocal().getHeight() / 2;

        double x = cx + hero.getLayoutX() + dx;
        double y = cy + hero.getLayoutY() + dy;

        moveHeroTo(x, y);
    }

    private void moveHeroTo(double x, double y) {
        final double cx = hero.getBoundsInLocal().getWidth()  / 2;
        final double cy = hero.getBoundsInLocal().getHeight() / 2;

        if (x - cx >= 0 &&
            x + cx <= W &&
            y - cy >= 0 &&
            y + cy <= H) {
            hero.relocate(x - cx, y - cy);
        }
    }

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

答案 1 :(得分:2)

Scene myScene = new Scene();

KeyCombination cntrlZ = new KeyCodeCombination(KeyCode.Z, KeyCodeCombination.CONTROL_DOWN);
myScene.setOnKeyPressed(new EventHandler<KeyEvent>(){
    @Override
    public void handle(KeyEvent event) {
        if(contrlZ.match(event)){
           //Do something
        }
    }
});

答案 2 :(得分:0)

使用 JNativeHook: https://github.com/kwhat/jnativehook

<!-- https://mvnrepository.com/artifact/com.1stleg/jnativehook -->
<dependency>
  <groupId>com.1stleg</groupId>
  <artifactId>jnativehook</artifactId>
  <version>2.1.0</version>
</dependency>



    private void initKeyListener(Stage primaryStage){
    /* Note: JNativeHook does *NOT* operate on the event dispatching thread.
     * Because Swing components must be accessed on the event dispatching
     * thread, you *MUST* wrap access to Swing components using the
     * SwingUtilities.invokeLater() or EventQueue.invokeLater() methods.
     */
    try {
        GlobalScreen.registerNativeHook();
    } catch (NativeHookException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    GlobalScreen.addNativeKeyListener(new NativeKeyListener() {
        public void nativeKeyPressed(NativeKeyEvent e) {
            if ( (e.getModifiers() & NativeKeyEvent.CTRL_MASK) != 0
                    && (e.getModifiers() & NativeKeyEvent.ALT_MASK) != 0
                    && (e.getKeyCode() == NativeKeyEvent.VC_B)){
                logger.debug("key :Hide");
                primaryStage.hide();
            }
            if ( (e.getModifiers() & NativeKeyEvent.CTRL_MASK) != 0
                    && (e.getModifiers() & NativeKeyEvent.SHIFT_MASK) != 0
                    && (e.getModifiers() & NativeKeyEvent.ALT_MASK) != 0
                    && (e.getKeyCode() == NativeKeyEvent.VC_B)){
                logger.debug("key :Show");
                primaryStage.show();
            }
            //System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
        }

        public void nativeKeyReleased(NativeKeyEvent e) {
            //System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
        }

        public void nativeKeyTyped(NativeKeyEvent e) {
            //System.out.println("Key Typed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
        }
    });
    /*
    GlobalScreen.addNativeMouseListener(new NativeMouseListener() {
        @Override
        public void nativeMouseReleased(NativeMouseEvent arg0) {
            // TODO Auto-generated method stub
            System.out.println("MouseReleased()");
        }

        @Override
        public void nativeMousePressed(NativeMouseEvent arg0) {
            // TODO Auto-generated method stub
            System.out.println("MousePressed()");
        }

        @Override
        public void nativeMouseClicked(NativeMouseEvent arg0) {
            // TODO Auto-generated method stub
            System.out.println("MouseClicked()");
        }
    });
    */
}