13

Java で初めてのゲームを作成しています。ゲームはモノポリーです。ターンベースの構造 (プレイヤーのターンの管理) をモデル化するためにゲームをどのように設計するべきかについて悩んでいます。私は、1 人の人間が操作するプレーヤーと、1 人または複数の AI が操作するプレーヤーの両方がゲームをプレイできるようにしたいと考えています。

私の具体的な問題は、ゲーム ループを実装するかどうかわからないことです。これは、モノポリーのゲームに直接関連するプレーヤーと変数を管理できるループを意味します (各プレーヤーに自分のターンを促したり、次のプレーヤーにターンをインクリメントするか、各プレーヤーから順番にサイコロを振る)。私は、「ゲーム ループ」という用語のより低レベルの意味について言及しているわけではありません。これは、画面上にフレームを描画したり、物理演算を更新したり、特定の時間で AI を更新したりすることに関連しています。

私の理解では、必要なものを実装しようとするためのオプションは次のいずれかです。

  1. そのようなゲームループを持たない完全にイベント駆動型のプログラムを実装する、または
  2. ゲーム ループを実装します。これは、バックグラウンドで長時間実行され、ゲームが実行されている限り基本的に終了することはありません。これは、より手続き的なアプローチになります。

この問題を解決しようと最初に試みたとき、ゲーム ループが終了せず、実行中のスレッドを完全に消費していたため、UI がフリーズする問題に遭遇しました (これを説明するために非常に単純な while ループを作成しました)。 . そこでSwingWorker、ゲーム ループをカプセル化するために を作成することにしました。これで UI がフリーズする問題は解決しましたが、それでも間違った道を進んでいたのではないかと思いました。

原則として、Web 上のほとんどのアドバイスは一般的にイベント駆動型のアプローチを支持しているように思われるため、 を使用する現在の実装SwingWorkerは間違った方向への一歩である可能性があります。しかし、この特定のタスクに対して完全にイベント駆動型のシステムを実装する方法を完全に把握することはできません (ゲーム ループが存在しないことを意味します)。プレイヤーのターンを管理するためのループがどこかに存在しなければならないように思えます。

ここに私の具体的な質問があります:

  1. ゲーム ループ (私が説明しているように) は、モノポリーなどのターンベースのゲームに適していますか? 特に、プレーヤーのターンをキューに入れ、適切なプレーヤーに一度に 1 人のプレーヤーを順番に促します (および、の手順/シーケンス全体をキューに入れます)。ターンを構成するステップ)?
  2. プレイヤーのターンを管理するための純粋なイベント駆動型システムを作成する場合、各プレイヤーをどのように反復してターンを促し、ゲームが終了するまで反復し続けるのでしょうか?
  3. 上記の特定の問題を解決するためにゲーム ループを使用する場合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();
4

1 に答える 1

11

SirDarius からのコメントは的を射ています。

ただし、プレーヤーの順番を進めるような単純なことについては、本格的な有限状態マシンをわざわざ実装する必要はありません。

MVC に関して言えば、これは人間のプレイヤーに対して行うべきことです。

  • モデル:アクティブ プレイヤーを次のプレイヤーに進め、「ターン プロセス」を実行するためのメソッドを提供します (つまり、サイコロを振る、アクティブ プレイヤーのトークンを移動するなど)。ターン プロセスの多くはイベント ドリブンであるため、これらのメソッド呼び出しはコントローラーのイベント リスナーから行われます。

  • ビュー:アクティブ プレイヤーがターンを終了したときにイベントを発生させ、他のさまざまな入力でイベントを発生させます。

  • コントローラー:プレーヤーが自分のターンを終了するたびに、モデルに次のプレーヤーに進むように指示し、「ターン プロセス」を再度開始します。プレーヤーが入力を提供するたびに、モデルにターンの次の段階に進むように指示するイベントが発生します。

AIプレイヤーの場合、同じコードの大部分を使用できますが、ターンの進行をビューによって駆動することは意味がありません。代わりに、モデルには AI プレイヤー専用の別の「ターン プロセス」メソッドが必要になります。唯一の違いは、コードが一連のイベント リスナーではなく、ビューからの入力を待たずに連続して実行されることです。

于 2013-07-25T22:58:33.977 に答える