0

うまくいけば、これは十分に明確になるでしょう。

タイルで構成された 2D マップがあり、「水」がこのマップを通過するようにします。パイプから出て特定のタイルに到達し、水のようにすべてのタイルを満たして特定の他のタイルに到達する必要があります。現在、各タイルがノードであり、各ノードがその周囲のすべての適切なタイルに接続されているマップをゲームに入力しています。最初に x、次に y で並べ替えられた配列にノードを格納しています。さらに、一部のタイルは「ゲート」タイルであり、水の流れを止めることができます。これらはノード タイルの同じグリッドの一部であり、アクティブなときにフラグが立てられます。

問題は、水をどのように分散させるかです。

最初に、各パイプ (水をドロップする) に「現在」と「満杯」の水タイルのリストを追跡させ、「現在」のタイルに直接水を分散させ、次にそれらを「満杯」のリストに切り替えます。適切な。「現在の」リストは、既に「現在の」タイルの周囲のタイルを取得することで拡張されました。いずれにせよ、これはうまく機能し、水はうまく流れましたが、水の流れを止めたり、再び許可したりできるように、ゲートで機能させる方法がわかりませんでした。 ) 特定のポイントで。

現在、水が 1 つのタイルだけに落ちており、タイルに水が多すぎると、ランダムな隣接タイルに徐々に水が押し出されます (タイルがアクティブなゲートでない限り)。これは、水が「外側」に流れるのではなく、すでに満たされたタイルの周りに「跳ね返る」ことです。最終的にはそこにたどり着きますが、その流れはあまり自然ではありません。

これで私のジレンマは終わりです。

コードはpythonで書かれています。

編集:新しいアイデア。更新ごとに水を配置するのに適した空きタイルをパイプで検索することもできますが、これは非常に効率が悪いようです (特に複数のパイプがある場合)。

4

3 に答える 3

3

これはゲーム開発で多く出てきます-このテーマに関する多くのGDCトークとGamasutra/GameDeveloperマガジンの特集記事があります。私が思うに、あなたの目的に最適なのは、2003GDCのJosStamの「ゲーム用のリアルタイム流体力学」です。

彼は、線形バックトレースを介して移流を実行する簡単な方法について説明しています。これは、いくつかの問題がありますが、非圧縮性流体では非常にうまく機能します(つまり、ガスよりも水でうまく機能します)。線形バックトレースとは、基本的に、空間内の各ポイント(つまりタイル)で流体密度を表すグリッドを設定し、フレームごとに各ポイントにアクセスして、「周囲のポイントの圧力に基づいて、流体の可能性が高い場所を尋ねる」ことを意味します。から来るの?」これは、他の方法で解決するよりも簡単であることがわかります(「この時点からの流体はどこに行くのですか?」)。

Gamasutraの流体力学に関するMickWestの記事は、パフォーマンスを向上させる可能性のあるいくつかの方法でStamの論文を拡張しているので、そこから始めたいと思うかもしれません。

より完全なソリューションを提供する最近のIntelが後援するGameDevの記事もありますが、それはかなり複雑で、3Dのグラフィカルレンダリング側に焦点を当てています。

タイル状の2D流体力学の例については、 Dwarf Fortressを参照できますが、彼のソリューションには、高速で流れる流体または加圧された流体を処理する際に多くの問題があるようです。時々、彼の水はあなたが予想するよりもずっとゆっくりと移動したり、ブロックやコーナーに巻き込まれたりします。

これらの論文は、私がStack Overflowボックスに詰め込むよりもはるかに優れた数学とアルゴリズムを要約していますが、私も言いたい2つの一般的なポイントがあります。

  1. 水シミュレーションは非常に計算コストがかかります。Pythonで作業しているため、実際のパフォーマンスの問題が発生する可能性があります。ループに時間がかかりすぎてフレームレートが低下する場合に備えて、アルゴリズムをプロファイリングしてホットスポットを見つける手段を設定してください。高速なCベースの配列操作を取得するには、数値Pythonを使用する必要がある場合があります。
  2. ゲーム開発には、ほとんどの人が予想するよりもはるかに多くの数学があります!
于 2009-12-26T05:54:33.007 に答える
2

仮定に関するいくつかのヒューリスティック:

  • それぞれ正確に1つの正方形を占める個別の「ドロップ」
  • 水は、特定のタイルで1つ以上の高さに留まることはありません。
  • 水は常に継続します
  • 障壁が上がっているとき、それらは壁のようです
  • 障壁が下がっているとき、それらは開いた正方形のようです

すべての水たまりについて、エッジの横にあるエッジの正方形と開いた正方形のリストを維持します。

バリアが下がったとき

amend the lists of edge and open squares for any puddles that were touching it

障壁が上がるとき

if (it was covered)
    pick a non-wall square next to it at random, and add the drop from the barrier there.
amend the lists of edge and open squares for any puddles next to the block

ドロップを追加する場合:

if (the square "under" the pipe is empty)
   fill it
else
   consult the list of edge square associated with the pool under the pipe, and select the one closest to the pipe (if more than one is closest, choose from the candidates at random), and fill it.  
amend the lists of edge and open squares for the puddle (be prepared to merge with neighboring puddles if necessary)

ドロップを削除するとき

 find the edge (not open!) square farthest from the sink (or randomly select from the equivalent candidates), and empty it
 amend the lists of edge and open squares for the puddle

(ここで利用できるフリルは、他のシンクと等距離で囲まれた「最も遠い」ものを作成することです。これにより、水たまりの中央にある正方形がシンクの間にある場合、それらが空になる可能性があります)

これはあまり現実的ではなく、ダイナミクスについて話すことはできませんが、滴下パイプの「下」で継続的な水たまりを維持し、十分な滴下があれば利用可能なスペースを埋めます。

于 2009-12-26T04:55:07.290 に答える
0

あなたのモデルには電位差や圧力の概念が含まれていますか?

空のタイルの圧力がゼロで、満杯のタイルの圧力が 10 だとします。2 つのタイルの間にパイプがある場合、圧力を均等にするために水が流れ、ゲートがパイプを閉じて何も流れません。

于 2009-12-25T23:03:07.700 に答える