Java实现Space Invaders:主菜单开始按钮加载无FXML游戏的问题
问题:JavaFX主菜单按钮加载无FXML的游戏类
复刻Space Invaders游戏时,主菜单的开始按钮原本用于切换FXML界面,但游戏核心BedreSpaceApp没有对应的FXML文件,无法直接通过原有逻辑触发游戏加载。
解决方案
1. 重写MenuController的start方法
直接调用BedreSpaceApp的界面创建逻辑,替换或新增游戏场景,无需依赖FXML。
方式一:复用当前窗口(替换主菜单)
修改MenuController中的start方法,获取游戏根节点后替换当前窗口的场景:
public void start(ActionEvent event) { BedreSpaceApp gameApp = new BedreSpaceApp(); Parent gameRoot = gameApp.createContent(); Scene gameScene = new Scene(gameRoot); // 绑定游戏键盘事件 gameScene.setOnKeyPressed(e -> { switch (e.getCode()) { case A: gameApp.player.left(); break; case D: gameApp.player.right(); break; case SPACE: gameApp.shoot(gameApp.player); break; } }); // 获取当前窗口并更新场景 Stage currentStage = (Stage)((Node)event.getSource()).getScene().getWindow(); currentStage.setScene(gameScene); currentStage.show(); }
方式二:新开独立游戏窗口
如果需要保留主菜单窗口,可新建窗口加载游戏:
public void start(ActionEvent event) { BedreSpaceApp gameApp = new BedreSpaceApp(); Parent gameRoot = gameApp.createContent(); Scene gameScene = new Scene(gameRoot); // 绑定游戏键盘事件 gameScene.setOnKeyPressed(e -> { switch (e.getCode()) { case A: gameApp.player.left(); break; case D: gameApp.player.right(); break; case SPACE: gameApp.shoot(gameApp.player); break; } }); // 创建并显示游戏窗口 Stage gameStage = new Stage(); gameStage.setTitle("Space Invaders"); gameStage.setScene(gameScene); gameStage.show(); }
2. 调整BedreSpaceApp的访问权限
由于MenuController需要访问BedreSpaceApp中的玩家对象和射击方法,需将相关成员的访问权限从private改为public,或添加公共访问方法:
// 在BedreSpaceApp中修改player的访问权限 public GameObject player = new GameObject(300, 750, 40, 40, "player", 3, Color.BLUE); // 若需封装,可保留private并添加getter // private GameObject player = new GameObject(...); // public GameObject getPlayer() { return player; }
若使用getter,键盘事件中需改为gameApp.getPlayer().left()。
3. 优化BedreSpaceApp结构(可选)
将场景初始化和键盘事件绑定逻辑抽为公共方法,简化MenuController代码:
// 在BedreSpaceApp中新增方法 public Scene createGameScene() { Parent root = createContent(); Scene gameScene = new Scene(root); setupKeyHandlers(gameScene); return gameScene; } private void setupKeyHandlers(Scene scene) { scene.setOnKeyPressed(e -> { switch (e.getCode()) { case A: player.left(); break; case D: player.right(); break; case SPACE: shoot(player); break; } }); }
此时MenuController中可直接调用:
Scene gameScene = gameApp.createGameScene();
内容的提问来源于stack exchange,提问作者Chris Vaffel
相关产品推荐
相关产品推荐

