我正在尝试使用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分开,因此上面显示的代码更改不应该依赖于界面框架。
任何帮助?
答案 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();
}
显然,你如何实现这一点的细节取决于你的要求等,但这种一般方法应该适用于你需要的任何东西。