2Dサイドスクロールゲームで「部屋」を検出するにはどうすればよいですか?


24

Terrariaが「居住」を検出する方法など、ゲームで作成できる特定の種類の建物や部屋を認識するシステムを作成したいと考えています。そのゲームでは、一連の条件を満たすブロックのゾーンを構築することにより、タイルベースの世界で家を構築できます。

  1. ゾーンは、プレイヤーが配置したブロックによって「外側」から完全に隔離されています。
  2. ゾーンは5x7の長方形に収まります。
  3. 囲まれたエリアには、少なくとも1つのテーブル、1つの光源、椅子があります。
  4. ゾーンから出るドアがあります。
  5. Terrariaには、前景と背景の両方のタイルレイヤーがあります。ゾーンの背景全体をプレイヤーが配置したブロックで埋める必要があります。

プレーヤーが適切なサイズのエリアを構築したことを効率的に検出するにはどうすればよいですか?また、エリアに必要な家具/コンポーネントがすべて含まれていることを効率的に確認するにはどうすればよいですか?

すべての住宅の要件を満たすインテリアゾーンの例:

ここに画像の説明を入力してください


5
詳しく説明してもらえますか?「ビルドの種類」とはどういう意味ですか?また、テラリアの「居住地」とは何ですか?誰もがゲームは、また、あなたが助けに人々をしたい場合は、1つの問題に焦点を当て、そして質問は明確な答え(ない意見を)持っていることを確認することを果たしていることに留意してください
TomTsagk

1
タイプとは、使用されるさまざまなコンポーネント/タイルを意味します。私の質問は以下で解決します。助けてくれてありがとう、今後の質問についてもっと詳しく説明し、より具体的にしようと思います。
ベルナルドベッカー

1
余談ですが、部屋住居の間に違いがあることを確認してください。あなたの箇条書きリストは、あなたがそれらを同じ定義として見ることを示唆しています。一例として、Terrariaを使用して、敵が(例えば、テーブルの欠落、または唯一の5×5次元で)彼らは住居として資格がない場合でも、部屋に出現していない
Flater

回答:


37

私はTerrariaに精通していませんが、フラッドフィルアルゴリズムを使用して簡単に実行できます

ピクセルの代わりに、タイルをチェックし、チェックされたタイルごとに、アルゴリズムが他のタイルのチェックを続行できるかどうかを評価し、プロセス中に見つかったオブジェクトを配列またはリストに保存します。

アルゴリズムは、キャラクターがいるタイルから始まります。1秒ごと、2秒ごとに開始できます。最適な間隔を見つけるのは微調整の問題です。

また、アルゴリズムの実行が長すぎることを防ぐこともお勧めです。これは、実行ごとにアルゴリズムが実行できるタイルの数を制限することで実現できます。

編集

コメントで述べたように、プレーヤーがタイルを変更したときや、アルゴリズムを開始するam I modified?変数を持つタイルなど、アルゴリズムを開始するタイミングに他のアプローチを使用できますtrue。ただし、このアプローチには注意する必要があります。

  • 部屋の一部であるが、キャラクターがいるタイルではないタイルが変更された場合はどうなりますか?タイルが他のプレーヤーによって変更されたか、環境イベントが発生したか、タイルのライフタイムが終了した可能性があります。キャラクターは変更を認識せず、更新された部屋を検出するアルゴリズムを実行しません。エラーが発生しやすい状況です。

あなたのキャラクターがいないタイルでこれらの変更を検出するために、ある種のアプローチを実装できますが、インターバルでアルゴリズムを実行するのが最も簡単なアプローチであり、エラーが発生しにくいです。すべてのフレームでフラッドフィルを実行しないようにしてください。

編集の終わり


9
「プレイヤーが配置したブロック」タイルの間でのみ塗りつぶしをしないのはなぜですか?これにより、オープンエリアでの無限の塗りつぶしを防止または削減できます(洞窟/大邸宅が「プレイヤーが配置したブロック」で満たされない限り)。
jimbo1qaz

20
なぜ一定の間隔でこれを実行するのですか?確かに、ブロックが配置されたとき(または該当する場合は破棄され、これらのケースはおそらくブロックごとに償却された一定時間で実行できる)またはマップの特定の部分をロードするときに実行し、結果を保存しますそこ。
NotThatGuy

3
@immibis:Terrariaでは、フロアを変更する必要はないと確信しています。また、ゲームがタイルの配置者に基づいて部屋を認識する動作を変更することも期待していません。たとえば、崖に隣接して部屋を建てたらどうなりますか?
フラット

3
Terrariaは、背景の壁を置くために1つを必要とし、自然な背景の汚れ/岩で家を形成しません。プレイヤーが配置したブロックのみをチェックします。
loa_in_

3
CPUを節約するために、ブロックの変更時にのみアルゴリズムを実行し、各ブロックの状態を保存します。これで、それは簡単ですisRoom()
Herr Derb

3

@Ferreira da Selvaが言ったように、フラッドフィルアルゴリズムを試してください。ただし、アルゴリズムを実行するときにいくつかの異なる基準を使用して、アルゴリズムが囲まれているかどうかを判断できます。

たとえば、タイルごとに背景タイルがあるかどうかを確認し、ない場合は、囲まれていないことがわかります。または、複数のフレームに分割して遅延実行を実行し、プロセッサの負荷を軽減して遅延を減らすこともできます。または、プレイヤーが順守しなければならない部屋のサイズ制限を作成することもできます。

これらの組み合わせを使用すると、より効率的かつ効果的に行うことができます。


3

コンピュータサイエンスには2つの難しい問題があります。命名、キャッシュの無効化、オフバイワンエラー。

これはキャッシュ無効化の問題です。

「内部にある」という記録がある場合、ブロックが配置または削除されるたびに、塗りつぶしによってブロックとその領域を更新するのは非常に簡単です。

これを最適化するには、「内部」の階層のセットが必要な場合があります。

「セル」とは、プレーヤーが配置したブロック(特定のサイズまで)に囲まれた領域です。

「部屋」とは、背景タイルのあるセルです。

「内側」は、ドア、照明、椅子のある部屋です。

プレイヤーが配置した前景ブロックを配置するとき、時計回り/反時計回りに歩いて、新しいセルが形成されるかどうかを確認します。プレイヤーが配置した前景ブロックを削除する場合、セルが破損していないかどうかを調べます。破損している場合は、2つを結合して新しいセルが形成されるかどうかを確認します。

新しいセルが形成されるか、または形成されない場合、部屋または内部であることを確認します。

セルは、部屋にするために必要な背景タイルの数を追跡できます。次に、セルが形成されるとき、背景タイルがセルに追加またはセルから削除されるときの単純なカウントにより、それが部屋であるかどうかを判断できます。

同様に、Cellsは、椅子と光源(および実際にはあらゆる種類のオブジェクト)がいくつあるかを追跡できます。その後、内部チェックは簡単です。

入場のカウントも行うことができます。


そのため、マップに「セル」を追加します。タイルが追加または削除されると、場所のセルを確認し、セル内のカウントをインクリメント/デクリメントします。

時計回り/反時計回りの歩行を使用して、前景ブロックを追加または削除するときにセルの内部と外部を定義します。セルのサイズが制限されているため、このウォークには制限された数のステップが必要です。

おまけとして、部屋には各オブジェクトタイプの数があるため、「豪華な」部屋、「部屋は聖なる噴水に恵まれている」、または部屋について何か他のものについて話す安価な方法があります。(または、部屋のサイズに制限があるため、繰り返しを行うだけです。これによりキャッシュが削除されます)。

各場所は最大1つのセルにあるため、メインマップに各場所のセルIDを保存できます。


0

塗りつぶしアルゴリズムを使用する場合は、チェックするタイルごとに増分する変数も作成するため、35(7 * 5、部屋の最大サイズ)を超えるとチェックが停止します!


7 * 5は、部屋の中に収まらなければならない最小サイズの長方形です
リック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.