Javafx:一次多个侦听器

时间:2018-09-30 18:27:30

标签: java javafx keylistener

我试图用Javafx重新创建Pong游戏,但是我遇到了平台移动方面的问题。

我正在使用keylisteners和switch语句上下移动平台。左边的一个带有W和S,右边的一个带有Up和Down。

当我分别按下它们时,它可以正常工作,但是当我想同时移动它们时,它却不能工作。

    package application;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,700,400);
            primaryStage.setScene(scene);
            primaryStage.show();
            scene.setFill(Color.BLACK);

            Rectangle player1 = new Rectangle();
            player1.setWidth(10);
            player1.setHeight(50);
            player1.setY(175);
            player1.setX(10);
            player1.setFill(Color.WHITE);
            root.getChildren().add(player1);

            Rectangle player2 = new Rectangle();
            player2.setWidth(10);
            player2.setHeight(50);
            player2.setY(175);
            player2.setX(680);
            player2.setFill(Color.WHITE);
            root.getChildren().add(player2);


            scene.setOnKeyPressed(new EventHandler<KeyEvent>(){ 
                public void handle(KeyEvent event) {
                    switch(event.getCode()) {
                    case W: if(player1.getY() -3 >= 0) {player1.setY(player1.getY()- 4);} break;
                    case S: if(player1.getY() +53 <= 400) {player1.setY(player1.getY()+4);} break;
                    case UP: if(player2.getY() -3 >= 0) {player2.setY(player2.getY()- 4);} break;
                    case DOWN: if(player2.getY() +53 <= 400) {player2.setY(player2.getY()+4);} break;
                    }
                }
            });


        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

1 个答案:

答案 0 :(得分:2)

JavaFX在事件处理程序中仅处理一个KeyCode。因此,无法检查来自keyevent对象的多个键代码。但是,它确实处理按顺序方式按下的所有键控代码。因此,如果您一次按A&B,它将按它们按的顺序处理A&B的事件。因此,利用此功能,我们可以进行一些调整并处理多按键事件处理。

以您的示例为例,继续注册通过按下事件处理程序提供的所有键代码(在一组中)并相应地执行逻辑。并确保清除释放键上的设置。这样我们可以知道哪些键被按下了。

下面的代码演示了我上面的解释。它在您的示例中有效:)

final List<KeyCode> acceptedCodes = Arrays.asList(KeyCode.S, KeyCode.W, KeyCode.UP, KeyCode.DOWN);
            final Set<KeyCode> codes = new HashSet<>();
            scene.setOnKeyReleased(e -> codes.clear());
            scene.setOnKeyPressed(e -> {
                if (acceptedCodes.contains(e.getCode())) {
                    codes.add(e.getCode());
                    if (codes.contains(KeyCode.W)) {
                        if (player1.getY() - 3 >= 0) {
                            player1.setY(player1.getY() - 4);
                        }
                    } else if (codes.contains(KeyCode.S)) {
                        if (player1.getY() + 53 <= 400) {
                            player1.setY(player1.getY() + 4);
                        }
                    }
                    if (codes.contains(KeyCode.UP)) {
                        if (player2.getY() - 3 >= 0) {
                            player2.setY(player2.getY() - 4);
                        }
                    } else if (codes.contains(KeyCode.DOWN)) {
                        if (player2.getY() + 53 <= 400) {
                            player2.setY(player2.getY() + 4);
                        }
                    }
                }
            });