単一のタイル画像よりも大きい等角図の描画順序-描画順序アルゴリズム?


8

さまざまな画像を配置するアイソメマップがあります。ほとんどの画像は単一のタイルに収まりますが、一部の画像はわずかに大きくなります。たとえば、2x3タイルのサイズのベッドがあります。

これにより、一部のタイルが他のタイルと誤って重なるため、オブジェクトを画面に描画するときに問題が発生します。

私が知っている2つの解決策は、画像を1x1タイルセグメントに分割するか、たとえば各画像に番号を割り当てることによって、独自の描画順序アルゴリズムを実装することです。番号1の画像が最初に描画され、次に2、3などが描画されます。

誰か私が何をすべきかについてのアドバイスはありますか?

アイソメトリック画像を分割することは非常に明白ではないように思えます。画像のどの部分が特定のタイルに含まれるかをどのように決定しますか?すべての画像を手動で分割する余裕もありません。

描画順序アルゴリズムはより良い選択のように見えますが、実装が簡単になるかどうかはわかりません。私は頭の中で、1つの画像のインデックスを変更する状況に対処する方法を解決できません。誰かがこれについてのリソース/チュートリアルを持っているなら、私は最も感謝します。

回答:


3

必要なものは、ペインターのアルゴリズムと呼ばれます。

最初に、最悪のタイルを描画します。その上には、仮説やキャラクターが含まれています。

次に、次に近いものを描き、終了するまで繰り返します。

複数のタイルにまたがるオブジェクトには、アンカー/原点を宣言する必要があります。これは、描画されると、より大きなオブジェクトも描画されるグリッドセルです。原点は、オブジェクトがにじむすべてのセルが最初に描画された後に描画されるように選択されます。

質問に基づいて、原点はカメラに最も近いタイルになります。(菱形のタイルではなく正方形を使用している場合は、左下または右下のタイルを選択する必要があります。)

スクエアグリッドのサンプルコード。ダイヤモンドグリッドのループ方向を変更します。

for(int y = 0; y < GridHeight; ++y) {
    for(int x = GridWidth - 1; x > -1; --x) {
        MapCell cell = getMapCell(x,y);
        DrawTerrain(cell);
        if(cell.IsDoodadOrigin){
            DrawDoodad(cell);
        }
        if(cell.IsCharacterOrigin){
            DrawCharacter(cell);
        }
    }
}

これがどのように機能するのかわかりませんか?ボックスで完全に囲まれた2x3のベッドを想像してください。セルを反復処理するとき、大きなオブジェクトの「原点」に到達するまでに、ベッドの後ろと前にあるはずのボックスがすでに描かれているはずです。
Wozza

正解です。この手法は正方形のグリッドで機能します。また、四角いダッド/キャラクターを使用する対角線グリッドでも機能します。対角グリッド上の不規則な2x3形状には機能しません。
ジム

3

オブジェクトを1×1×1の立方体に分割し、各立方体に、その立方体に物理的に存在するオブジェクトの部分の写真を割り当てます。

これは、実際の3Dオブジェクトから開始して2Dにレンダリングする場合は簡単です。オブジェクトを2Dで直接描画している場合(または既存のアートを分割する必要がある場合)、手作業が必要です。幸い、特定の立方体に割り当てられたイメージパーツが六角形領域の外側にこぼれないことを確認する限り、分割は正確である必要はありません。グラフィックエディターで追加のレイヤーとして各キューブのアウトラインを表示するオーバーレイを作成すると役立つ場合があります。

次に、p = x + y + z(3つの座標すべてがカメラに向かって増加すると想定)として各キューブに優先度を割り当て、優先度の高い順にキューブをレンダリングします。


これはに基づく簡単な例です これは、Wikimedia Commonsのこの画像にPhasmatinox / AllefantによるCC-By-SA 3.0ライセンスで使用)。

        立方体に分割された拡張オブジェクトの等角投影

写真のチェストには2つのタイルが使われ、その上にそれらのタイルの境界(赤い六角形)を描画しました。各六角形の内側にある画像の部分は、対応するタイルに割り当てる必要があります。選択が最終結果に影響しないため、六角形が重なっている部分をどちらかのタイル(または必要に応じて両方)に割り当てることができます。

1つのタイル内に複数のオブジェクト、タイル間の壁/床、またはタイル間をスムーズに移動するオブジェクト(人など)を配置できる場合は、この単純なアルゴリズムについて詳しく説明する必要があることに注意してください。壁と床は扱いが非常に簡単です。壁と床は、前にあるタイルのコンテンツの後(カメラの視点から)、後ろにあるタイルの前であればいつでも描画できます。これは、タイル間を移動するオブジェクトの経験則でもあります。それらをタイルの間の壁と同じように扱います。

タイルで複数のオブジェクトについては、時々それらは非常に単純です:あなたは写真の胸の上に横たわって本を持っていた場合、たとえば、それは明らかにそれが上にあり、表面の後に描画する必要があります。ただし、たとえば、人が座ることができるオブジェクトがある場合、状況はさらに複雑になる可能性があります。たとえば、人がカメラに背を向けてベンチに座っていた場合、人の体はベンチの後ろに描かれる必要がありますが、脚(カメラからベンチの後ろにある)はその前に描かれる必要があります。この場合の解決策の1つは、座っている人の脚を、独自の位置(隣接するタイル内、またはタイル間)を持つ個別のコンポーネントに分割することです。


1

タイプまたは高度によってオブジェクトを分割するのに役立ちますたとえば、風景(床、壁)はオブジェクト(ベッド)の前に描画する必要があります。また、等角投影法のため、標高の高いタイルの前に標高の低いタイルを描画する必要があります。

また、インデックス番号付け(実際にはZ順序)を使用する場合は、番号の間にギャップを使用することをお勧めし1ます2。床やベッドを作成しないでください。floors = 10やbed = 20などの何かを使用100して、ドミノをインクリメントせずに途中に「挿入」できるようにします。


最初の段落であなたが提案することをするつもりです。私が抱えている問題は、類似したタイプのオブジェクトが誤って重なり合っていることです。たとえば、私のベッドがベッドサイドテーブルと重なっています。たとえば、画像の各インスタンスに異なる番号を付けることを提案しましたが、たとえば、すべてのベッドに番号20を与えるのではありませんか?
ロジャー・スミス

場合によります。2つのベッドが隣接している場合はどうなりますか?多くの場合、これを回避する1つの方法は、描画する順序でオブジェクト追加することですが、それが役立つかどうかはわかりません。
ashes999

1
2つのベッドが隣り合っている場合は、y値の高いベッドを他のベッドの上に描画する必要があります。それらが同じy座標である場合、xの値が最も高いもの(マップの上部が(0,0)であると想定)
Roger Smith
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.