9

等尺性の壁に問題があります。

背面から前面へのレンダリング方法を使用してアイソメトリック フロア タイルを描画していますが、正常に動作します。また、床のタイルをきれいなグリッドに適切に並べています。コードは次のとおりです (これは等角図の床の描画ではほぼ標準のようです)。

for(int x = 0; x < 6; x++){
    for(int y  = 3; y >=0 ; y--){

        int xCo = (y+x)*(tileWidth/2);
        int yCo = (x-y)*(tileHeight/2);
        tile.draw(g, xCo, yCo);
    }            
}

これにより、すてきな小さな床ができます。

複数の床タイル

グリッドは次のタイルから構築されます。

単一のタイル

残念ながら、壁に同じロジックを使用すると、すべてがうまくいきません。

for(int x = 0; x < 6; x++){
    for(int y  = 3; y >= 0 ; y--){

        int xCo = (y+x)*(wallWidth()/2);
        int yCo = (x-y)*(wallHeight()/2);
        walls.draw(g, xCo, yCo);    
}
}

私はこれを壁のタイルとして使用しています:

シングルウォールタイル

(これは Google 画像検索のプレースホルダーですが、すべて同じように機能するはずです)

これは私が得る結果です:

複数の壁タイル

壁のレンダリング順序は明らかに正しく、近い壁は遠い壁の上にレンダリングされます。これは私が望んでいるものですが、配置も痛々しいほど間違っています。ピクセル値。

参考までに、ハードコーディングされたピクセル値を使用して試行を行いました。これは、ある壁の右隅から次の壁の右隅への変化が正確に (200, -100) ピクセルであることがわかったためです。そのためのレンダリング ループ アカウントを作成したとき

int xCo = (x+y)*200;
int yCo = (y-x)*-100;

うまくいきましたが、汎用性がないため、実行可能なソリューションではありません。

だから、等尺性の壁を一列に並べる方法についての提案を探しています。私は何を間違っていますか?

ありがとう!

4

3 に答える 3

2

壁と床は同じ平面上にないため、単純に床と同じ描画コードを壁に使用することはできません。床は平ら (水平) ですが、壁は垂直です。そのため、少し異なる方法で描画する必要があります。

フロアケースの x 座標と y 座標は、タイルの配置に関して「左/右」および「前方/後方」のようなものを意味します。レンガの場合、左右はまだ意味がありますが、垂直方向を反映するために、前後を上下に置き換えたいと考えています。したがって、「y」は新しい意味を持ちます。

現在、数学では y 軸は通常上向きですが、2D コンピュータ グラフィックスでは下向きです。y = 0以下のコードは、「床の高さ」を意味する上向きであると想定しています。

それでは、順番について考えてみましょう。あなたが投稿したレンガの例は、床の(上)左端になる壁用です。レンガの黒い部分 (壁の深さ) があるため、左側の黒い深さが近くにあるレンガで覆われるように、最初に右にあるレンガを描画する必要があります。同じ議論が壁の上部の黒にも当てはまります。最初に下部のレンガを描く必要があります。

前に説明したように x 方向と y 方向 (x は左から右、y は下から上) に固執する場合、これは両方の for ループを負の方向に実行する必要があることを意味します。

    for (int y = 3; y >= 0; y--) {
        for (int x = 5; x >= 0; x--) {
            ...
        }
    }

主な問題は、各レンガの図面を他のレンガに対してどれだけオフセットする必要があるかということです。x 方向から始めて、一度に 1 方向ずつ行いましょう。

隣り合った 2 つのレンガだけを想像してみましょう。

2 つのレンガを水平に

2 つのうち左側には黒い深度部分が表示されていますが、右側には表示されません。したがって、右の画像を PNG の全幅だけ単純にオフセットすることはできません。実際、レンガが床のタイルに沿って並んでいると仮定すると、壁の実際の前部の幅はタイルの幅の半分と同じになるはずです。

int xCo = x * tileWidth / 2;

左側の黒い壁の深さは無視しないでください。おそらく、各レンガを少し左にオフセットして、壁の前隅の x 座標が床のタイルと並ぶようにする必要があるからです。バックコーナーのコーディネート。

ここで、各ブリックの y 座標は、ブリックの行だけでなく、x 座標にも依存するため、少し複雑です。右に行くほど上に描画する必要があります。しかし、x 方向をしばらく無視して、単純にレンガの列を描画してみましょう。

垂直に 2 つのレンガ

繰り返しますが、2 つのブリックの y 座標間のデルタは、PNG の高さ全体ではありません。デルタ x として使用できるようにレンガがタイルと並んでいると仮定した左/右のケースとは異なりtileWidth、レンガは任意の高さを持つことができます。ただし、画像の高さから実際のレンガの高さを計算することはできます。これは、左側の奥行きと上部の奥行きが一致する必要があることがわかっているためです。

レンガ PNG の右上隅にある小さな透明な三角形を見ると、その幅と高さの比率が床タイルの幅と高さの比率と同じでなければならないことがわかります。これにより、上で計算した xoffset から yoffset を計算し、それを使用してレンガの実際の高さを推測できます。

int yoffset = xoffset * tileHeight / tileWidth;
int wallHeight = wallHeight() - tileHeight / 2 - yoffset;

これは、PNG の境界に空きスペースがなく、丸め誤差のために失敗する可能性があるという前提の下でのみ機能することに注意してください。したがって、必要に応じてここにMath.ceil()(または単に) を追加できます。+ 1

yしたがって、単純な列の場合は、これで準備完了です。変数に上記の を単純に掛けることができますwallHeight。ただし、前述のように、レンガの x 位置も y ピクセル座標に影響します。2 つのレンガが隣り合っている最初の写真をもう一度見てみると、右のレンガをどれだけ上に動かして左のレンガと並べる必要があったでしょうか? 床タイルと同じでタイルの半分の高さなので、実は簡単です。

これで準備完了です。すべてをまとめると、次のようなコードになります。

int xoffset = wallWidth() - tileWidth / 2;
int yoffset = xoffset * tileHeight / tileWidth;
int wallHeight = wallHeight() - tileHeight / 2 - yoffset;

for (int y = 3; y >= 0; y--) {
    for (int x = 5; x >= 0; x--) {

        int xCo = x * tileWidth / 2;
        int yCo = y * wallHeight - x * tileHeight / 2;

        walls.draw(g, xCo - xoffset, yCo - yoffset);
    }
}

(wallWidth() と wallHeight() がブリック PNG の幅と高さを返すと仮定しています。)

for ループの前の 3 つの定数は、実際の描画コードから移動できることに注意してください。これらは、画像のプロパティとその他の定数にのみ依存し、壁を描画するたびに再計算する必要はありません。

于 2013-01-23T23:43:24.730 に答える
0

ひし形の床タイルを見ると、幅の半分、長さの半分だけ上に移動すると、2 つのエッジが揃います。
壁のタイルはひし形ではないため、幅の半分、長さの半分を移動すると、一致させたいエッジが揃いません。

与えられuた = 横に移動するv距離、 = 上に移動する距離A、等角

v = u*tan(A)

uこの場合は、画像の前面の幅です。

壁の画像の面 (テクスチャ ビット) が床タイルのエッジの長さと一致する場合、これは次のようになります。

int offset = ?;// this is the width of the black stripe on the image.

for(int x = 0; x < 6; x++){
    for(int y  = 3; y >=0 ; y--){

        int xCo = ((y+x+1)*(tileWidth/2))-offset;
        int yCo = (x-y)*(tileHeight/2);
        wall.draw(g, xCo, yCo);
    }            
}
于 2013-01-23T21:42:58.057 に答える
0

アイソメトリック領域では、移動できる軸が 3 つあります。Z は上下、X と Y は「対角線」です。

最初に、1 単位 x 1 単位 x 1 単位のアイソメトリック キューブのピクセル表現を想像してみましょう。すべての辺が同じ長さで表現されています。

Z 軸上で A ピクセルの高さになります。他のエッジも長さが A ピクセルになりますが、60 度回転します。したがって、高さは sin(30)*A ピクセル、X 方向と Y 方向の長さは cos(30)*A ピクセルになります。つまり、0.5*A と sqrt になります。 (3)/2 *A.

したがって、等角キューブ サイズのオブジェクトを X、Y、Z に配置するには、画面上の x と y を次のように変換する必要があります。

y += Z*A
x += X*A/2 - Y*A/2
y += (X+Y)*A*sqrt(3)/2

私が立てた仮定が成り立つ限り、これは機能するはずです。

EDIT:ちなみに、画像に奥行きがある場合は A をハードコーディングする必要があるため、画像の寸法から A を自動的に抽出することはできません。

于 2013-01-23T22:03:54.843 に答える