現在、XNA ゲームのプロトタイプに取り組んでいます。ゲームの世界の等角投影ビューを実現しようとしています (または正投影ですか?? この投影法に適切な用語がどれかはわかりません - 写真を参照してください)。世界は、立方体のタイルで作られたタイルベースの世界 (たとえば、Minecraft の世界に似ています) である必要があり、スプライトを使用して 2D でレンダリングしようとしています。
そのため、立方体の上面、前面、および側面 (目に見える側) の面を持つスプライト シートがあります。drawSprite への 3 つの個別の呼び出しを使用してタイルを描画します。1 つは上、もう 1 つは側面、もう 1 つは前面です。ソースの四角形を使用して描画する面を選択し、宛先の四角形を使用して画面上の位置を設定します。 3D ワールド座標からアイソメ (正投影) に変換する式に変換します。
(サンプルスプライト:
)
これは、顔を描いている限りうまく機能しますが、(タイル グリッドに従って) 各ブロックの細かいエッジを描画しようとすると、いくつかの線が顔自体によって上書きされ、ランダムなレンダリング パターンが得られることがわかります。そうでないものもあります。
私の世界表現では、X は左から右、Y は画面の内側から画面の外側、Z は上から下にあることに注意してください。
この例では、上面エッジのみを使用しています。これが私が得るものです(写真):
一部の行が表示され、一部の行が表示されない理由がわかりません。私が使用するレンダリング コードは次のとおりです (この例では、各次元の最上位レイヤーのみを描画していることに注意してください)。
/// <summary>
/// Draws the world
/// </summary>
/// <param name="spriteBatch"></param>
public void draw(SpriteBatch spriteBatch)
{
Texture2D tex = null;
// DRAW TILES
for (int z = numBlocks - 1; z >= 0; z--)
{
for (int y = 0; y < numBlocks; y++)
{
for (int x = numBlocks - 1; x >=0 ; x--)
{
myTextures.TryGetValue(myBlockManager.getBlockAt(x, y, z), out tex);
if (tex != null)
{
// TOP FACE
if (z == 0)
{
drawTop(spriteBatch, x, y, z, tex);
drawTop(spriteBatch, x, y, z, outlineTexture);
}
// FRONT FACE
if(y == numBlocks -1)
drawFront(spriteBatch, x, y, z, tex);
// SIDE FACE
if(x == 0)
drawSide(spriteBatch, x, y, z, tex);
}
}
}
}
}
private void drawTop(SpriteBatch spriteBatch, int x, int y, int z, Texture2D tex)
{
int pX = OffsetX + (int)(x * TEXTURE_TOP_X_OFFRIGHT + y * TEXTURE_SIDE_X);
int pY = OffsetY + (int)(y * TEXTURE_TOP_Y + z * TEXTURE_FRONT_Y);
topDestRect.X = pX;
topDestRect.Y = pY;
spriteBatch.Draw(tex, topDestRect, TEXTURE_TOP_RECT, Color.White);
}
最初のループの後に 2 つ目の 3 層のネストされた for ループを作成して、別のアプローチを試してみました。また、各タイルを描画するためにメソッドを呼び出すこともおそらく避けますが、今のところ機能させようとしています)。
結果はいくらか良くなりましたが、まだ期待どおりに動作していません。一番上の行がありません。画像を参照してください。
なぜ私がこの問題を抱えているのか分かりますか? 最初のアプローチでは、Z ファイティングのようなものかもしれませんが、スプライトを正確な順序で描画しているので、既にあるものを上書きしてはいけませんか?
みんな、ありがとう