在JavaFX中等待子任务完成

时间:2016-01-18 15:55:37

标签: java javafx-8

我正在尝试使用JavaFX创建一个简单的游戏。游戏包括主游戏和子游戏,玩家可能必须根据主游戏的结果进行游戏。最后,主要游戏必须根据子游戏结果更新它的状态(p.e。:得分)。

我制作了一个简化的通用版本,说明了我如何实现游戏逻辑:

Result play(Player p) {
    Result r = p.play(this);
    for(SubGame game : r.getSubGames())
    {
        p.play(game);
    }
    update(r);
    return r;
}

这款游戏在终端中运行完美,因为它具有线性执行功能。 但是使用JavaFX(在播放器中实现),由于游戏循环,我无法正确控制程序的流程。

我已经按照this教程处理主游戏和子游戏的多个屏幕。 Player类可以使用处理程序成功地将屏幕更改为子游戏。但是更新不再等待子游戏的播放,并且当玩家处于游戏中期时此功能会返回。

我试图将游戏逻辑与UI分开,因此上面显示的代码更改不应该依赖于界面框架。

任何帮助?

1 个答案:

答案 0 :(得分:1)

使用事件驱动的方法,设置可观察属性的值,并在它们发生变化时进行响应。

例如,您可以使用

封装游戏的状态
public class GameState {

    private ObservableList<SubGame> currentGames = FXCollections.observableArrayList();

    public ObservableList<SubGame> getCurrentGames() {
        return currentGames();
    }

    private ReadOnlyObjectWrapper<SubGame> currentGame = new ReadOnlyObjectProperty<>();

    public ReadOnlyObjectProperty<SubGame> currentGameProperty() {
        return currentGame.getReadOnlyProperty() ;
    }

    public final SubGame getCurrentGame() {
        return currentGameProperty().get();
    }

    public GameState() {
        // initialize sub game list...
    }

    public void nextGame() {
        int index = currentGames.indexOf(currentGame.get());
        if (index < currentGames.size() - 1) {
            currentGame.set(currentGames.get(index + 1));
        }
    }

    public void start() {
        currentGame.set(currentGames().get(0));
    }

    public boolean hasMoreGames() {
        return currentGames.indexOf(currentGame.get()) < currentGames.size() - 1 ;
    }
}

同样地,您的SubGame班级可能会有一些可观察的状态:

public class SubGame {

    private final BooleanProperty finished = new SimpleBooleanProperty();

    public BooleanProperty finishedProperty() {
        return finished ;
    }

    public final boolean isFinished() {
        return finishedProperty().get();
    }

    public final void setFinished(boolean finished) {
        finishedProperty().set(finished) ;
    }

    // ...
}

现在你的游戏逻辑只是由听众实现:

void play(Player p) {
    Result r = p.play(this);
    GameState gameState = new GameState();
    gameState.currentGameProperty().addListener((obs, oldGame, newGame) -> {
        newGame.finishedProperty().addListener((obs, wasFinished, isNowFinished) -> {
            if (isNowFinished) {
                // maybe update score etc based on state of newGame...
                if (gameState.hasMoreGames()) {
                    gameState.nextGame();
                } else {
                    // logic here for "all games are finished...
                }
            }
        });
    });
    gameState.start();
}

显然,你如何实现这一点的细节取决于你的要求等,但这种一般方法应该适用于你需要的任何东西。