2D手続き型地形生成-接続性を保証しますか?


7

XNAで2Dプラットフォーマーを開発しています。主なデザイン特性になりたいことの1つは、手続き型コンテンツの生成です。その最初のステップは、地形を手続き的に生成することです。だから、私はPerlinノイズを生成し、それを滑らかにし、パラメーターとすべてのジャズをいかにプレイするかについて、たくさんの研究をしました。pcg.wikidot.comにも多くの時間を費やしました。私が抱えている問題は、100%接続されているレベルを生成することです。つまり、キャラクターがレベルの左側から右側に到達する可能性があります。

現在、パーリンノイズを使用して、そのポイントのノイズ値が<0のときにスプライトを生成しています。

これは私が抱えている問題のビデオです(クレイジーなバックグラウンドの問題と、新しいレベルを生成するときにキャラクターが動かなくなるという事実を許してください)。

http://screencast.com/t/uWJsIGLoih

ビデオでわかるように、地形は十分に興味深いように見えますが、Perlinノイズがレベルを小さなランダムなチャンバーに区分化しているため、それほど多くのことはできません。

ランダムウォークを実行し、その上にパーリンノイズを重ねようとしたので、左から右へのパスを保証します。その問題を以下に示します。http//screencast.com/t/ilLvxdp3

だから私の質問は、プレーヤーがレベルの左側から右側に行くことができるようにするには、どうすればよいですか?

回答:


13

接続性」という言葉を使用すると、解決策を決定するのに最も適したツール:グラフ理論の範囲内に入ることができます。

接続性はグラフのプロパティです。グラフは接続されていても切断されていてもかまいません(経験上、マルチグラフとも呼ばれます)。あらゆる次元のあらゆるゲームレベルをグラフとして表すことができ、論理的には、これが多くの場合、それらを操作するための最良の方法です。あなたのゲームの世界は、あなたの世界の個々のビルディングブロック間の隣接性の観点からのグラフです。また、さまざまな領域間の接続性のレベルでも。前者を使用して後者を導出できます。

(2D)レベルをグラフとして操作する際に考慮すべき重要なポイントがあり、それが平面性です。要件によっては、平面性が問題になる場合と問題にならない場合があります。ノイズの使用を考えると、後者を期待していますが、ここでオプションの概要を説明して、それらが何であるかを理解できるようにします。

平面グラフ -最も単純な例は迷路です。迷路は分岐を含まないという点で迷路とは異なります-それは一筆書きです。植え込み(!)の固いブロックを取り、そこからラビリスを生成する場合、迷路が取る方向転換は、既存のパスにぶつかることはありません。これは、実際には蛇のゲームに少し似ています。パスが蛇の体である場合、それ自体を噛んだり交差させたりすることはできません。さらに、あなたは平面迷路を持つことができます。これは分岐しますが、迷路の場合と同様に、分岐が既に生成された迷路の既存の部分と交差することは許可されません。

非平面グラフ -最も単純な例は都市の街路図です。都市は本質的に迷路です。しかし、ある場所から別の場所へ行くには多くの個別の道路ルートがあるという点で、それは高度に接続された迷路です。さらに、非平面グラフの埋め込みにより、交差が可能になります。交差はまさに交差です。そして私たちが知っているように、都市は交差点のない都市ではありません。それらはトラフィックフローに不可欠です。ゲームでは、目標に応じてこれは良い場合も悪い場合もあります。優れたレベルのフローにより、AIはより簡単に行動でき、探索はより自由になります。その一方で、プレーヤーはスタートポイントからゴールまですばやく、可能性としてはあまりにも早く到達することもできます。

これにより、ノイズを使用するというアプローチが可能になります。パーリンノイズの出力に応じて、マクロスケールとしてある程度の接続性を持たせることができますが、1つの接続性(単一のグラフ)向けには設計されていません。これにはいくつかのオプションがあります。

  1. Perlinノイズの使用を削除し、代わりにランダムな平面(非交差)の接続グラフを生成します。これにより、最大のフロー制御が提供されます。ただし、グラフの平面性はクラトフスキーサブグラフK3、3、およびK5の識別と削除を必要とするため、このアプローチは重要です。それに続く平面埋め込みの作成。どちらもNP完全問題です。これは間違いなく最も難しいアプローチですが、自分の立場を知るために最初に言及する必要がありました。他のすべてのメソッドは、このメソッドを中心としたある種のショートカットです。これは、迷路生成の背後にある基本的な計算です。

  2. パーリンノイズの使用を中止し、代わりに平面サーフェスに埋め込まれたランダムな非平面グラフ(別名、平面埋め込み)を生成します-これにより、ディアブロやローグライクのようなゲームは、両方ともグリッドを使用するため、簡単に機能させることができます平面空間を分割する構造(実際、ローグライクのレベルの大部分は、4方向の交差の数で明らかなように、交差を許可しています)。セルまたはテンプレートルーム間の接続を生成するアルゴリズムは、固体の岩のブロックから徐々に空のスペースを切り分けるため、「カーバー」または「タンナー」と呼ばれることがよくあります。

  3. オプション(2)として行いますが、交差は避けてください。したがって、両方の埋め込み(レベルジオメトリ)は平面であり、トポロジ(レベルフロー)も平面です。交差を避けたい場合は、行き止まりに陥らないように注意する必要があります。

  4. ノイズを使用してマップを生成します。次に、接続されていないレベル(マルチパートおよびグリッドベースではありますが、グラフです)のすべてのセルに塗りつぶしアルゴリズムを使用して、そのより大きなマルチグラフ内のすべての接続されていない離散サブグラフを推定できます。次に、個々のサブグラフをどのように接続するかを検討します。交差を避けたい場合は、これらを順次接続することをお勧めします。そうでない場合は、自由に接続できます。これを有機的に行うために、ハードな直線の通路を作成するのではなく、ある種のコヒーレンス関数を使用して、サブグラフの各ペアの最も近い点を結合します(順次リンクしている場合)。これにより、結合がより「流動的」になり、通常のPerlin出力と一致します。エリアに参加するもう1つの方法は、エリアを互いに近づける方法です。

  5. ノイズを使用して非常に大きなマップを生成します。オプション3で説明されているように、すべてのサブグラフを分離します。特定の基準に従って、最も興味深いものを特定します(サイズなどの可能性がありますが、サイズが最も簡単です)。すでに完全に自己接続されているそのサブグラフのみを選択して使用します。このアプローチの難しさは、ブルートフォースで非常に大きなマップまたは多数の小さなマップを生成して完璧なサブグラフを選択しない限り、結果のグラフのサイズを制御するのが難しい場合があることです。これは、サブグラフのサイズが実際に使用されるPerlinパラメータと結果の解釈方法に依存するためです。

最後の2つはさておき、あなたが既に行ったことは確かですが、念のため:Flashで最小限のPerlinノイズテストケースを作成します。「アイランド」エリア間の接続の度合いが高くなるまで、パラメータをいじってください。パーリンノイズには接続性の本質的な保証がないため、これがすべての世代にわたって100%問題を解決することはないと思います。しかし、それはつながりを改善する可能性があります。

あなたが理解していないものは何でも、尋ねてください、そして私は明確にします。


これは素晴らしい答えです。
tenpn

1
それから、あなたは森で最も強力な木を切り倒さなければなりません...ニシンと一緒に!
ジョナサンコネル

ははは…ええ
エンジニア

このソリューションはまだ実装していませんが、提供された情報からいくつかのことを考え直すことができ、私の質問に最もよく答えたと思います。だから、私はそれを答えとしてマークしています。皆さんありがとう。
SpaDusA 2011

5

この問題への一般的なアプローチ:

  1. 最初から接続性を保証する方法でマップを作成します。PCG wikiのダンジョンジェネレーターの多くはこのように動作します。
  2. 切断されている可能性のあるマップを生成し、接続性をチェックする何か(おそらくパスファインダー)を記述します。機能しないマップを破棄します。
  3. 切断されている可能性のあるマップを生成し、接続されていないときはいつでも修正します。チェックアルゴリズムが通過できない領域を見つけたときはいつでも、トンネルを爆破し、橋を建設し、テレポーターを追加します。
  4. 切断されている可能性のあるマップを生成し、必要に応じて接続するためのプレーヤーツールを提供します。切断されたマップのバグを機能に変換します。Terraria、Minecraftなどがこれを行います。
  5. 切断される可能性のあるマップを生成し、レベルを完了できない場合は、プレーヤーを再起動するか、別のレベルに移動します。一部のローグライクがこれを行うと思います。

ノイズ関数はおそらく理想的ではないかもしれませんが、ノイズ関数は多くのことを実行でき、何らかの方法で修正できる可能性があることをカイロタンに同意します。いくつかのアイデアについては、この記事を参照してください。


2

そのビデオは混乱を招くだけで、正直に言うと何を見せようとしているのかわかりません。しかし、私は、Perlinノイズがおそらくこの仕事には不適切なアルゴリズムであることを示唆します。連続したエンティティを滑らかに波打つように設計されていますが、分散した個別のエンティティを作成しようとしています。おそらくより適切に機能するのは、ランダムな値を使用して、プラットフォームの手で設計された配置を再配置および調整して、結果の領域が再生可能であることを確認することです。

Spelunkyがこれをどのように実行したかに関するいくつかの情報があります:http : //tinysubversions.com/2009/09/spelunkys-procedural-space/


0

高さに基づいてパーリン値を変更してみてください。つまり、下部でノイズ値に1を加算し、上部でノイズ値から1を減算し、その間に1と-1の間を線形補間します。このようにして、下部ではほぼ確実に0以上の値が得られ、上部ではほとんど0以下の値が得られます。

これは、値<0が空気であると想定されていることを想定しています。説明が正しいことを理解した場合は、切り替える必要があります。

乾杯。


1
だから私はあなたの方法を試してみましたが、次の結果が得られました:screencast.com/t/vxnc0LHbLGPQ それが私の問題を解決したかどうか本当にわかりません。接続を確実にするために、私はまだ後処理をする必要があります。
SpaDusA 2011

0

既存のコードを前提として簡単に採用できるシンプルなアプローチは、接続性の制約を満たすまでランダムマップを生成し続けることです。

開始位置からの塗りつぶしを使用して、接続制約をすばやく確認することができます。それは合法的なエンドポイントに至るまで満たされますか?

1秒間に数千のそのようなチェックを実行できるため、おそらく完全に受け入れ可能なハックです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.