英文:
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语言的经验与见解,让所有开发者获益!
评论