当我使用while循环时,JavaFX程序没有启动



好的,所以我正在尝试使用JavaFX制作一个带有GUI的基于文本的游戏。在我进入真正的游戏循环之前,一切都很顺利。尽管一旦我把代码放进游戏循环中,程序就不会启动。它运行时不会出现错误或异常,但窗口根本不会弹出。当我关闭窗口时,IntelliJ中的所有命令行都显示"进程已完成,退出代码为130",这显然意味着程序已关闭,因为用户按下了Ctrl+C。事实并非如此,因为窗口甚至没有弹出,所以任何用户都不可能点击Ctrl+C来终止程序。所以我的问题是,我该怎么做才能在没有窗口拒绝弹出的情况下,用游戏循环(while循环)运行我的程序。这是我的代码:

package sample;
/**
 * Created by Angel on 7/26/16.
 */
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class Game {
    // Inventory is a class that i made,
    // but im sure it has nothing to do with my problem
    private Inventory inv = new Inventory();
    private String levels;
    private Scene scene;
    private Label topText;
    private Button btn1;
    private Button btn2;
    private Button btn3;
    private boolean gameOn;
    public void gameStart(){
        // Setting the GUI
        // Setting up the window
        VBox window = new VBox(210);
        // setting up the top text holder.
        HBox textHolder = new HBox();
        textHolder.setAlignment(Pos.CENTER);
        // setting up the label
        topText = new Label();
        topText.setText("You in a dark room, what do you do?");
        // setting up the button holder
        HBox buttonHolder = new HBox(50);
        buttonHolder.setAlignment(Pos.CENTER);
        // setting up the buttons
        btn1 = new Button();
        btn1.setPrefWidth(260);
        btn1.setPrefHeight(30);
        btn1.getStyleClass().add("gameButtons");
        btn1.setText("1");
        btn2 = new Button();
        btn2.setPrefWidth(260);
        btn2.setPrefHeight(30);
        btn2.getStyleClass().add("gameButtons");
        btn2.setText("2");
        btn3 = new Button();
        btn3.setPrefWidth(260);
        btn3.setPrefHeight(30);
        btn3.getStyleClass().add("gameButtons");
        btn3.setText("3");

        // finalizing the gui, by putting it all together
        textHolder.getChildren().add(topText);
        buttonHolder.getChildren().addAll(btn1, btn2, btn3);
        window.getChildren().addAll(textHolder, buttonHolder);
        // setting up the scene
        scene = new Scene(window, 800, 600);
        //adding the css script
        // adding css script
        scene.getStylesheets().add(this.getClass().getResource("game.css").toExternalForm());
        // the game loop.
        levels = "Storyline";
        gameOn = true;
        while(gameOn) {
            switch (levels) {
                case "Storyline":
                    btn1.setText("search around");
                    btn2.setText("turn the light on");
                    btn3.setText("stand in fear");
                    btn2.setOnAction(e -> levels = "level1");
                    break;
                case "level1":
                    topText.setText("You turned the light on");
                    break;
            }
        }
    }
    public Scene getScene(){
        return scene;
    }
}

这不应该是一个游戏循环。单击按钮会触发一个事件。应该在那里处理。没有必要一次又一次地更新按钮文本等等,这就是你目前正在做的。

通过在那里执行循环,您可以阻塞应用程序线程,该线程负责重新绘制和处理用户交互,使其无法完成任务。

重新调整代码以工作基于事件的,即

用户交互(单击按钮)触发ui更新(状态的更改和ui的单个更新)。

例如:

public class Game {
    ...
    public void gameStart(){
        ...
        // setting up the scene
        scene = new Scene(window, 800, 600);
        // adding css
        scene.getStylesheets().add(this.getClass().getResource("game.css").toExternalForm());
        setLevel("Storyline");
    }
    public void setLevel(String newLevel) {
         // TODO: integrate gameOn value
         if (newLevel != null && !newLevel.equals(levels)) {
              levels = newLevel;
              switch (levels) {
                case "Storyline":
                    btn1.setText("search around");
                    btn2.setText("turn the light on");
                    btn3.setText("stand in fear");
                    // user interaction triggers setting the level
                    btn2.setOnAction(e -> setLevel("level1"));
                    break;
                case "level1":
                    topText.setText("You turned the light on");
                    break;
            }
         }
    }
    ...
}

附加建议:不要将级别表示为String,将其表示为实现接口的实例:

public interface Level {
     // do updates for level start on game
     void updateGameLevelStart(Game game);
     // cleanup code e.g. unregistering event handlers...
     void updateGameLevelEnd(Game game);
}

这将允许您将levels的类型更改为Level,并简化更新:

public void setLevel(Level newLevel) {
     if (!Objects.equals(levels, newLevel)) {
         if (levels != null) {
              // cleanup old level
              levels.updateGameLevelEnd(this);
         }
         levels = newLevel;
         if (newLevel != null) {
              // start new level
              newLevel.updateGameLevelStart(this);
         }
     }
}

这当然需要您使ui的相关部分可供Level实现访问。

相关内容

  • 没有找到相关文章

最新更新