英文:
KeyEvents with Nested Anchor Panes in JavaFX Scene
问题
我有一个名为GameSceneController的类,其中有一个AnchorPane字段,目的是将其分配给不同的'Game Rooms'。我有一个名为GamePaneController的类,它是FXML的控制器。
我正在尝试使自定义的'sprite'类在嵌套的anchorpane内部通过箭头键按键移动。我可以通过按钮来实现它,但每次按箭头键时,它会突出显示场景根中的按钮,而不是在窗格内移动精灵。
谢谢!
这是我的代码:
处理'outer' AnchorPane的GameSceneController。
public class GameSceneController implements Initializable, SceneController {
    private GameController gc;
    private Sprite charSprite;
    private Scene menuScene;
    private Scene gameScene;
    private String[] panePaths = {"fxml/Room1.fxml", "fxml/Room2.fxml", "fxml/Room3.fxml"};
    private GamePaneController gPaneController;
    // testing
    int gCtr = 0;
    @FXML
    Button gCtrPress;
    @FXML
    Button nextRoomButton;
    @FXML
    AnchorPane gamePane;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        gamePane.getChildren().add(new Region()); // this group
    }
    // 其他代码...
}
处理'nested' AnchorPane的GamePaneController。
public class GamePaneController implements Initializable {
    private GameController gc;
    private Scene gameScene;
    private Sprite charSprite;
    @FXML
    AnchorPane gamePane;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        System.out.println("DEBUG - Game Controller");
    }
    // 其他代码...
}
GameScene FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<AnchorPane
    prefWidth="1080"            
    prefHeight="720"
    xmlns:fx="https://google.com/"
    fx:controller="io.javasmithy.controller.scene.GameSceneController">
    <children>
        <AnchorPane fx:id="gamePane" AnchorPane.leftAnchor="100" AnchorPane.topAnchor="100" prefHeight="600" prefWidth="800"/>
        <Label text="Game SCENE" fx:id="gameSceneTitle" AnchorPane.leftAnchor="310" AnchorPane.topAnchor="10"/>
        <Button fx:id="gCtrPress" text="inc Ctr" onAction="#moveBtn" AnchorPane.leftAnchor="800" AnchorPane.topAnchor="800"/>
        <Button fx:id="menuButton" text="mainMenu" onAction="#openMenuScene" AnchorPane.leftAnchor="10" AnchorPane.topAnchor="10"/>
        <Button fx:id="nextRoomButton" text="Next Room" onAction="#setGamePane" AnchorPane.leftAnchor="900" AnchorPane.topAnchor="600"/>
    </children>
</AnchorPane>
'nested' AnchorPane的FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:id="gamePane"
            fx:controller="io.javasmithy.controller.scene.GamePaneController"
            prefHeight="600.0" prefWidth="800.0"
            stylesheets="@/style/GamePaneStyle.css"
            styleClass="background">
    <children>
        <Label text="Room 1" AnchorPane.topAnchor="10" AnchorPane.leftAnchor="25"/>
    </children>
</AnchorPane>
如果您想查看Sprite类,这是它的代码。
public class Sprite extends Rectangle {
    private static final Random random = new Random();
    int row;
    int column;
    PointGrid grid;
    public Sprite(PointGrid grid) {
        super();
        this.grid = grid;
        this.row = 0;
        this.column = 0;
        setWidth(32.0);
        setHeight(32.0);
        setPos();
    }
    // 其他代码...
}
英文:
I have a GameSceneController class that has an AnchorPane field, with the intention of assigning it to different 'Game Rooms'. I have a GamePaneController that is the controller for the FXML.
I am trying to make a custom 'sprite' class move inside of the nested anchorpane with arrow key presses. I can achieve it via button, but every time I press the arrow keys, it highlights the buttons in the scene root rather than moving the sprite within the pane.
Thanks!
Here is my code:
GameSceneController handling the 'outer' AnchorPane.
public class GameSceneController implements Initializable, SceneController {
    private GameController gc;
    private Sprite charSprite;
    private Scene menuScene;
    private Scene gameScene;
    private String[] panePaths = {"fxml/Room1.fxml", "fxml/Room2.fxml", "fxml/Room3.fxml"};
    private GamePaneController gPaneController;
    // testing
    int gCtr = 0;
    @FXML
    Button gCtrPress;
    @FXML
    Button nextRoomButton;
    @FXML
    AnchorPane gamePane;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        gamePane.getChildren().add(new Region()); // this group
    }
    public void setMenuScene(Scene scene) {
        this.menuScene = scene;
    }
    public void setGameScene(Scene scene){
        this.gameScene = scene;
    }
    //   TESTING
    @FXML
    public void gCtrInc() {
        //gc.run(); //  TESTING
        if (gCtr < 2){
            gCtr++;
        } else {
            gCtr = 0;
        }
        System.out.println(gCtr);
    }
    //  TESTING
    @FXML
    public void openMenuScene(ActionEvent actionEvent) {
        Stage primaryStage = (Stage) ((Node) actionEvent.getSource()).getScene().getWindow();
        primaryStage.setScene(menuScene);
    }
    @Override
    public void setGameController(GameController gc) {
        this.gc = gc;
        setSprite();
    }
    public void setSprite(){
        this.charSprite = this.gc.getSprite();
    }
    @FXML
    public void setGamePane(ActionEvent actionEvent) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource(panePaths[this.gCtr]));
        this.gamePane.getChildren().set(0, loader.load());
        gPaneController = loader.getController();
        gPaneController.setGameController(this.gc);
        gPaneController.setGameScene(this.gameScene);
        gCtrInc();
    }
    @FXML
    public void moveBtn(ActionEvent actionEvent){
        System.out.println("DEBUG: " +   ((AnchorPane)this.gamePane.getChildren().get(0)).getChildren());
        System.out.println(gPaneController.getSprite());
        gPaneController.getSprite().moveColumn(1);
    }
}
GamePaneController handling the 'nested' AnchorPane.
public class GamePaneController implements Initializable {
    private GameController gc;
    private Scene gameScene;
    private Sprite charSprite;
    @FXML
    AnchorPane gamePane;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        System.out.println("DEBUG - Game Controller");
    }
    public void setGameScene(Scene scene){
        this.gameScene = scene;
        setUserKeyInput();
    }
    public void setUserKeyInput(){
        this.gamePane.setOnKeyPressed(e -> {
            e.consume();
            if (e.getCode() == KeyCode.UP) {
                this.charSprite.moveRow(-1);
            } else if (e.getCode() == KeyCode.DOWN) {
                this.charSprite.moveRow(1);
            } else if (e.getCode() == KeyCode.LEFT) {
                this.charSprite.moveColumn(-1);
            } else if (e.getCode() == KeyCode.RIGHT){
                this.charSprite.moveColumn(1);
            } else {};
        });
    }
    public void setGameController(GameController gc) {
        this.gc = gc;
        setSprite();
    }
    public void setSprite(){
        this.charSprite = this.gc.getSprite();
        this.gamePane.getChildren().add(this.charSprite);
    }
    public Sprite getSprite(){
        return this.charSprite;
    }
}
GameScene FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<AnchorPane
prefWidth="1080"            
prefHeight="720"
xmlns:fx="https://google.com/"
fx:controller="io.javasmithy.controller.scene.GameSceneController">
    <children>
        <AnchorPane fx:id = "gamePane" AnchorPane.leftAnchor="100" AnchorPane.topAnchor="100" prefHeight="600" prefWidth="800"/>
        <Label text="Game SCENE" fx:id="gameSceneTitle" AnchorPane.leftAnchor="310" AnchorPane.topAnchor="10"/>
        <Button fx:id="gCtrPress" text="inc Ctr" onAction="#moveBtn" AnchorPane.leftAnchor="800" AnchorPane.topAnchor="800"/>
        <Button fx:id="menuButton" text="mainMenu" onAction="#openMenuScene" AnchorPane.leftAnchor="10" AnchorPane.topAnchor="10"/>
        <Button fx:id="nextRoomButton" text="Next Room" onAction="#setGamePane" AnchorPane.leftAnchor="900" AnchorPane.topAnchor="600"/>
    </children>
</AnchorPane>
FXML for the 'nested' AnchorPane
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:id="gamePane"
            fx:controller="io.javasmithy.controller.scene.GamePaneController"
            prefHeight="600.0" prefWidth="800.0"
            stylesheets="@/style/GamePaneStyle.css"
            styleClass="background">
    <children>
        <Label text="Room 1" AnchorPane.topAnchor="10" AnchorPane.leftAnchor="25"/>
    </children>
</AnchorPane>
Sprite Class in case you want to see it.
public class Sprite extends Rectangle{
    private static final Random random = new Random();
    int row;
    int column;
    PointGrid grid;
    public Sprite(PointGrid grid){
        super();
        this.grid = grid;
        this.row = 0;
        this.column = 0;
        setWidth(32.0);
        setHeight(32.0);
        setPos();
    }
    public void moveRow(int delta){
        if (row + delta < 0 || row + delta > this.grid.getHeight()-1) {
            return;
        } else {row+=delta;}
        setPos();
    }
    public void moveColumn(int delta){
        if (column + delta < 0 || column + delta > this.grid.getWidth()-1) {
            return;
        } else {column+=delta;}
        setPos();
    }
    private void setPos(){
        this.setX(grid.getPoint2D(row, column).getX());
        this.setY(grid.getPoint2D(row, column).getY());
    }
    public void moveRandomly(){
        int axis = random.nextInt(2);
        int direction = random.nextInt(2);
        int delta = 1;
        if (direction == 0) delta = -delta;
        if (axis ==0 ) {moveRow(delta);} else {moveColumn(delta);}
    }
}
专注分享java语言的经验与见解,让所有开发者获益!

评论