0

現在、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 ファイティングのようなものかもしれませんが、スプライトを正確な順序で描画しているので、既にあるものを上書きしてはいけませんか?

みんな、ありがとう

4

3 に答える 3

1

おっと、すみません、私はばかです:) SpriteBatch.begin(SpriteSortMode.BackToFront)でバッチを開始しましたが、描画にz値を使用しませんでした。SpriteSortMode.Deferredを使用する必要がありました!現在は正常に動作しています。みんな、ありがとう!

于 2010-11-30T22:53:17.143 に答える
0

ソースとデスティネーションの四角形のサイズを 1 ~ 2 ピクセル微調整してみてください。これは、これらの長方形がレンダリングされる領域の一種の「アウトライン」として処理され、一種のオフバイワンの問題として処理される方法に関係があるのではないかと疑っています。これは専門家のアドバイスではなく、仲間のコーダーの直感です。

于 2010-11-30T22:41:47.073 に答える
0

サブピクセルの精度またはスケーリングの問題のようです。また、テクスチャ/タイルの幅/高さが 2 の累乗 (32、64、128 など) であることを確認してください。これにより、効果も悪くなる可能性があります。それらの写真だけでは本当にわかりにくいです。

すべてをスケーリングする方法/場合はわかりませんが、可能な限り(特にdrawTop()メソッド内で)丸めを避けるようにしてください。いくつかの位置/座標の可能性を丸めるたびに、エラー/ランダム オフセットが増加する可能性があります。整数の代わりに double (またはより良い: float) 座標を使用してみてください。

于 2010-11-30T22:45:56.973 に答える