0

私はテキストベースのRPGを作成していますが、時間をエミュレートしたいと思っています。
プレイヤーが何かを入力するたびに少し時間が経過することもできますが、可能であればそれよりも優れていると思います。マルチスレッドがこれを行うための良い方法であるかどうか疑問に思いました。

私は、バックグラウンドに、1000ミリ秒ごとにループするループを持つ2番目の本当に単純なスレッドがあるのではないかと考えていました。ループを通過するたびに、ワールドタイムが1秒増加し、プレイヤーは少しの体力とマナを再生します。

これはマルチスレッドで実行できることですか、それとも私が知らないことがこれを機能させないものがありますか?(このプロジェクトで役に立たない場合は、これを学ぶのに苦労して多くの時間を費やしたくないです。)

4

3 に答える 3

3

はい、マルチスレッドは確かにこれを行うことができますが、スレッドは通常、代替(メインループの一部としてさまざまな更新イベントをポーリングするメインスレッドであり、少なくとも100ミリ秒ごとに1回程度実行する必要があります)よりも複雑であることにうんざりしています)。

あなたの場合、クロックスレッドがかなり厳格なルールに従っている場合は、おそらく「大丈夫」です。

  1. クロックスレッドは、時間変数を設定/変更できる唯一のスレッドです。
  2. main / uiスレッドは、時刻の読み取りのみが許可されています。
  3. スレッドスリープ関数は正確性を信頼できないため、システム時間関数を使用する必要があります(システムアクティビティによっては、スレッドの更新ループは、実行を要求してから数ミリ秒後まで実行されない場合があります)。

そのように実装すれば、スレッドを安全に稼働させるためにミューテックスに精通する必要さえなく、時間は正確になります。

だが!ここにいくつかの考えの糧があります:1日の特定の時間にゲーム内トリガーをバインドしたい場合はどうなりますか?たとえば、ユーザーに「太陽が沈んだ」などのメッセージが投稿されます。そのために必要なコードは、とにかくメインスレッドで実行する必要があり(クロススレッドメッセージ通信キューを実装する場合を除く)、基本的な定期的なチェックと更新のクロックコードに非常によく似ています。 。したがって、その時点では、とにかく単純な統合スレッドモデルを維持する方がよいでしょう。

于 2013-02-25T04:51:28.347 に答える
0

私は通常、シミュレーションという名前のクラスを使用して時間を進めます。私はC++にはありませんが、Javaでスレッド化を実行しました。これは、時間を進め、スケジュールに従ってイベント(または計画された時間のランダムイベント)をアクティブ化するものです。これを利用してC++に変換するか、オブジェクト指向の実装がどのようになっているのかを確認するために使用できます。

package adventure;

public class Simulation extends Thread {

    private PriorityQueue prioQueue;

    Simulation() {
        prioQueue = new PriorityQueue();
        start();
    }

    public void wakeMeAfter(Wakeable SleepingObject, double time) {
        prioQueue.enqueue(SleepingObject, System.currentTimeMillis() + time);
    }

    public void run() {
        while (true) {
            try {
                sleep(5); 

                if (prioQueue.getFirstTime() <= System.currentTimeMillis()) {
                    ((Wakeable) prioQueue.getFirst()).wakeup();
                    prioQueue.dequeue();
                }

            } catch (InterruptedException e) {

            }

        }
    }

}

これを使用するには、インスタンス化してオブジェクトを追加するだけです。

 `      Simulation sim = new Simulation();

        // Load images to be used as appearance-parameter for persons
        Image studAppearance = loadPicture("Person.gif");

        // --- Add new persons here ---
        new WalkingPerson(sim, this, "Peter", studAppearance);
于 2013-02-25T06:04:07.603 に答える
0

現在、プログラムはユーザー入力の待機に大部分の時間を費やしていると想定します。これにより、メインスレッドが不規則に比較的長期間ブロックされ、時間に依存する短い更新ができなくなります。そして、複雑なソリューション(スレッド化)を避けたいということです。

メインスレッドの時刻にアクセスしたい場合は、別のスレッドなしで時刻にアクセスするのは比較的簡単です(例を見てください)。

ユーザーの入力を待っている間、バックグラウンドで何もする必要がない場合、待っている間に経過した時間に基づいて新しい値を計算する関数を作成できませんでしたか?LastSystemTimeObserved時間依存変数の1つを使用する必要があるたびに更新される変数を持つことができます-毎秒値を再計算する代わりに、最後に呼び出されてから経過した時間に基づいて変数の変更された値を計算する関数を呼び出します。

別のスレッドを作成する場合は、両方のスレッドがアクセスする変数を適切に保護するようにしてください。

于 2013-02-25T06:08:43.133 に答える