6

私はJavaを学んでいるので、基本的なテキストベースのゲームを作り上げようとしています。特定のイベントのペースを管理する手段として、ゲーム内のラウンドをカウントできるようにしたいと思います。たとえば、部屋の変更はラウンドごとに1回に制限できます(テストコードでは1秒)。小さなクリーチャーはより高い割合で部屋を攻撃または変更する可能性がありますが、大きなクリーチャーはより厄介になる可能性があります。これまでのところ良いですか?素晴らしい。

それで、私はこれを作り上げて、whileループがプレーヤーがコマンドを入力するのを待つたびにブロックにぶつかることにすぐに気づきました。コード:

private void startPlaying() {
    //declare clock/round variables.
    int lastRound = 0;
    int currentRound = 0;
    long lastTime = System.currentTimeMillis();
    long currentTime;

    while (player.getIsPlaying()){
        //Clocking
        currentTime = System.currentTimeMillis();
        if ((lastTime + 1000) < currentTime) {
            lastTime = currentTime;
            lastRound = currentRound;
            currentRound++;
            System.out.println("Current round:\t" + currentRound + "\tCurrent time:\t" + currentTime); //EDIT:NOTE: This is just a test line to observe the loop.
        }//end if (Clocking)

        Command command = new Command();
        String[] commandString = command.setAll(); //Array gets parsed elsewhere.
        player.doCommand(commandString);  
        //Class Player extends Pawn extends Actor; Pawn has most command methods.
    }
    finishPlaying();
}//END STARTPLAYING()

だから、ここに私の質問があります:

別の方法を使用して、whileループと同時にプレーヤーにコマンドプロンプトを表示する時間/ラウンドをログに記録する方法はありますか?

そうでない場合、これを私がまだ見ていない/実践していない問題ではないようにする別の方法はありますか?

4

4 に答える 4

4

Concurrency tutorialを見てください。スレッドを使用すると、他のプロセスを停止せずにユーザー入力を待つことができます (そして、これらの他のプロセスを同時に実行させます - 並列ではなく時分割)。

于 2013-03-20T17:07:22.777 に答える
1

これを「ゲームループ」と呼び、ユーザーの入力に関係なくスムーズにゲームが進行するようにしています。

最も簡単な解決策 - 2 つのスレッドを作成します。frist はユーザー入力を待機し、それConcurrentLinkedQueueを容量 1 に入れます。2 番目のスレッドはゲーム ループを実行し、キューが空でない場合はキューからユーザー入力を取得して処理します。

2 つのスレッド間でデータを交換する任意のデータ構造を使用できます。揮発性の文字列変数であってもかまいません。この変数への読み取り/書き込みアクセスの唯一の要件は、何らかの方法で同期する必要があります。

于 2013-03-20T17:12:50.630 に答える
1

リアルタイムのテキストアドベンチャー?興味深いですね。この特定の問題に対して同時実行を試みることはお勧めしません。もっと簡単な方法があります。

通常、入力のブロックと時間 (秒単位) を混在させることはありません。このデザインにこだわる場合を除き、どちらかをお勧めします。

1) ユーザー入力をブロックしないでください。フレームごとにキーの押下をチェックして、独自の入力処理コードを記述します。次に、反復間の時間差を計算できます。たとえば、モンスターは 1 ブロック秒移動するため、現在のループ反復に 100 ミリ秒かかった場合、0.1 ブロック移動します。float(テキスト グリッドに描画する場合でも、これらの値を s として内部的に保存します。

2) ユーザー入力に基づいてゲーム時間を「ティック」単位で増やします。これは NetHack/Roguelike スタイルです。モンスターは、毎秒ではなく、ティックごとに非常に多くのブロックを移動できます。

于 2013-03-20T17:13:54.927 に答える
1

はい、方法があります。「Round Counting」コードを独自のスレッドに配置する必要があるため、データの入力を待機しているユーザーによってブロックされません。パッケージはこれjava.util.concurrencyに役立ちます。

Java Docを見て、scheduleAtFixedRate() メソッドが固定間隔でランナブルを実行します。「ラウンド カウント」コードは、実行可能なインターフェイスを実装するクラスに移動されます。そして、これは設定された時間間隔で実行されます。ただし、これはかなり高度です。

于 2013-03-20T17:14:31.793 に答える