Java で初めてのゲームを作成しています。ゲームはモノポリーです。ターンベースの構造 (プレイヤーのターンの管理) をモデル化するためにゲームをどのように設計するべきかについて悩んでいます。私は、1 人の人間が操作するプレーヤーと、1 人または複数の AI が操作するプレーヤーの両方がゲームをプレイできるようにしたいと考えています。
私の具体的な問題は、ゲーム ループを実装するかどうかわからないことです。これは、モノポリーのゲームに直接関連するプレーヤーと変数を管理できるループを意味します (各プレーヤーに自分のターンを促したり、次のプレーヤーにターンをインクリメントするか、各プレーヤーから順番にサイコロを振る)。私は、「ゲーム ループ」という用語のより低レベルの意味について言及しているわけではありません。これは、画面上にフレームを描画したり、物理演算を更新したり、特定の時間で AI を更新したりすることに関連しています。
私の理解では、必要なものを実装しようとするためのオプションは次のいずれかです。
- そのようなゲームループを持たない完全にイベント駆動型のプログラムを実装する、または
- ゲーム ループを実装します。これは、バックグラウンドで長時間実行され、ゲームが実行されている限り基本的に終了することはありません。これは、より手続き的なアプローチになります。
この問題を解決しようと最初に試みたとき、ゲーム ループが終了せず、実行中のスレッドを完全に消費していたため、UI がフリーズする問題に遭遇しました (これを説明するために非常に単純な while ループを作成しました)。 . そこでSwingWorker
、ゲーム ループをカプセル化するために を作成することにしました。これで UI がフリーズする問題は解決しましたが、それでも間違った道を進んでいたのではないかと思いました。
原則として、Web 上のほとんどのアドバイスは一般的にイベント駆動型のアプローチを支持しているように思われるため、 を使用する現在の実装SwingWorker
は間違った方向への一歩である可能性があります。しかし、この特定のタスクに対して完全にイベント駆動型のシステムを実装する方法を完全に把握することはできません (ゲーム ループが存在しないことを意味します)。プレイヤーのターンを管理するためのループがどこかに存在しなければならないように思えます。
ここに私の具体的な質問があります:
- ゲーム ループ (私が説明しているように) は、モノポリーなどのターンベースのゲームに適していますか? 特に、プレーヤーのターンをキューに入れ、適切なプレーヤーに一度に 1 人のプレーヤーを順番に促します (および、の手順/シーケンス全体をキューに入れます)。ターンを構成するステップ)?
- プレイヤーのターンを管理するための純粋なイベント駆動型システムを作成する場合、各プレイヤーをどのように反復してターンを促し、ゲームが終了するまで反復し続けるのでしょうか?
- 上記の特定の問題を解決するためにゲーム ループを使用する場合
SwingWorker
、UI のフリーズを回避するために、ゲーム ループを独自のスレッド内で (おそらく を使用して) 実行する必要がありますか? 私の状況は Java 固有のものですが、Java 固有でない状況に対する回答にも興味があると思います。
現在、MVC パターンを使用してコードを編成しています。コントローラーは、ゲーム ループ (実際のSwingWorker
スレッド) が存在する場所です。これはまだ完全ではありませんが、私が「ゲーム ループ」と呼んでいるものでプレイヤーのターンをどのように管理しているかを説明するのに役立ちます。
SwingWorker
コントローラーからのコード:
swingWorker = new SwingWorker<Void, Model>() {
@Override
protected Void doInBackground() throws InterruptedException {
gameLoopRunning = true;
while (gameLoopRunning) {
//to do: use a timer instead of thread.sleep
Thread.sleep(1000);
//user turn prompt
if (model.getActivePlayer().isUserControlled()) {
boolean userRolled = false;
while(!userRolled) {
System.out.println("Roll the dice please...");
Thread.sleep(3000);
}
}
//bot turn prompt
else {
//insert code for bot rolling dice here
model.rollDice();
}
publish(model);
Thread.sleep(1000);
model.incrementPlayerTurn();
publish(model);
}
return null;
}
@Override
protected void process(List<Model> chunks) {
Model gameModel = chunks.get(chunks.size() - 1);
//hard-coded for 6 players
for (int i = 0; i < 6; i++) {
view.getPlayerPanel(i).setTurn(gameModel.getPlayers().get(i).isTurn());
}
view.getGamePanel().getDice().setDie1(model.getDie1());
view.getGamePanel().getDice().setDie2(model.getDie2());
}
};
swingWorker.execute();