5

状況: シミュレートされた環境にいくつかのエンティティがあり、「ティック」と呼ばれる人工的な時間の概念があり、リアルタイムとは関係ありません。各エンティティは順番に移動しますが、一部のエンティティは他のエンティティよりも高速です。これは、ティック単位の遅延で表されます。したがって、エンティティ A の遅延は 10 で、B の遅延は 25 である可能性があります。この場合、順番は次のようになります。

ああああ

私はどのデータ構造を使用するのか疑問に思っています。最初は「優先キュー」と自動的に考えましたが、遅延は「現在の時間」に関連しているため、問題が複雑になります。また、より大きな遅延が発生するエンティティがあり、プログラムが何百万回も実行されることは予測できません。遅延自体が比較的小さく、増加しない場合に、内部カウンターがどんどん高くなっていくのはばかげているように思えます。

では、これをどのように解決しますか?

4

5 に答える 5

4

エンティティをヒープに格納し、残りの待機時間でグループ化します。次に移動するエンティティのグループは、ヒープの一番上になります。これらのエンティティを更新するだけです。残りの待機時間が 0 になったら、ヒープから削除します。エンティティの次のグループをヒープの一番上に配置し、前の移動の直前に経過した時間だけ待機時間を減らします。

例えば:

ヒープには 3 つのノード (A、B、および C) があり、一番上はノード A で、2 つのエンティティが両方とも 5 ティック残っています。子には、それぞれ 10 と 12 のティックが残っています。

  • t=5 の時点で、ノード A でバケット化されたすべてのエンティティを移動します。
  • A をヒープから削除する
  • B がヒープの一番上に移動し、残り 10-5 = 5 ティック
  • 繰り返す。
于 2010-03-13T04:41:10.547 に答える
1

あなたの説明では、「次は何?」という概念のように思えます。「次のアクションまであとどれくらいか」よりも重要です。この場合、キューを「次へ」または残りのティック数が最も少ない順に並べ替えます。もちろん、挿入は適切な順序で入力され、変更されたエントリ (「スピードアップ」呪文) はキューから削除され、変更され、適切に再入力されます。

次に、次のジョブをキューからポップします。残りのティックの数は、「経過時間」でなければなりません。キューをパスし、各エントリの残りティック数フィールドを、発見したティック数だけ減らします。

これには、残り時間の概念を追跡するという利点がありますが、実行するアクションがないときに経過するティックに対してイベントを発生させたり、他のコードを実行したりする必要がないという利点もあります。リアルタイムとはまったく関係がないので、これは余裕です。「次は何?」と「そこにたどり着くのにどのくらいかかりましたか?」しかありません。

于 2010-03-13T04:21:13.550 に答える
0

オプション #1: ポーリング

おそらく、すべての異なるエンティティの遅延を検出し、各エンティティのティック残りを維持できるコントローラーを構築します。コントローラーはティックを循環し、ティックごとに、ゲーム内のすべてのエンティティの残りのティックを減らします。

エンティティの ticks-remaining 値が 0 に達すると、ティックを処理する heartbeat メソッドまたは呼び出すメソッドによって制御される番であることがわかります。

オプション #2 イベント

UI パラダイムのように考えてください。インターフェイスは、ボタンがいつクリックされたかを確認するために常にボタンをポーリングするわけではありません。むしろ、イベントを介してクリックされたときに、ボタンが UI に通知するようにします。エンティティ (または EntityBattleContext) が準備ができたら、イベントを発生させます。ゲーム時間は現実世界の時間にまったく基づいていないため、何らかの方法でゲーム時間を処理する必要があります.

イベント ドリブン ルートに従う前に、ポーリング ルートが機能しないことを確認してください。基本的なルールは常に後で最適化することを覚えておいてください。最適化が必要ない場合が多いためです。

于 2010-03-13T04:15:01.647 に答える
0

エンティティがシミュレーション時間を観察または監視していると仮定すると、それらはそれぞれ、追跡するインターフェイスを実装ticks leftし、特定のエンティティに残っているティック数を取得する方法を提供できます。各ティックで、エンティティはその値ticks leftを 1 減らします。

get ticks left0 番目のエンティティが次に移動するエンティティであり、N 番目のエンティティが「最も遅い」エンティティになるように、これらのエンティティの並べ替えられたセット キュー (各エンティティが一度だけキューに入るために設定) を に基づいて並べ替えることができます。 .

エンティティのget ticks leftメソッドが 0 の場合、エンティティはソート済みセットから削除され、ticks leftタイマーがリセットされ、ソート済みセットに再挿入されます。

于 2010-03-13T04:17:48.650 に答える
0

Java のDelayQueueがどのように実装されているかを見てください。

于 2010-03-13T07:07:18.537 に答える