2010-11-30 11 views
0

現在、XNAゲームのプロトタイプを作成中です。私はゲーム世界の等角図を達成しようとしています(または、この投影について正しい言葉がどれかわかりません - 写真参照)。 世界はキュービックタイルで作られたタイルベースの世界です(たとえばMinecraftの世界に似ています)。スプライトを使用して2Dでレンダリングしようとしています。XNAアイソメトリックタイルレンダリングの問題

私は、立方体の上面、正面、側面(目に見える側)の面を持つスプライトシートを持っています。 3つの別々のdrawSeleを使ってタイルを描画します.1つは上部、もう1つは正面、もう一つはソース矩形を使用して描画したい面を指定し、送り先の矩形を使用して画面上の位置を設定します3D世界座標を等値(正射法?)に変換する式に変換します。

(サンプルスプライト: Sprite

これは、限り、私は顔を描くように良い作品が、私は(タイルグリッドごとに)各ブロックの細かいエッジを描画しようとする場合、私は私が得ることがわかりますいくつかの線は面自体によって上書きされ、一部は上書きされないランダムなレンダリングパターン。

私の世界表現では、Xは左から右に、Yは外から画面に、Zは上から下に向かって表示されます。

この例では、最前面エッジのみで作業しています。ここで私は(絵)得るものです:

alt text

線の一部が表示されている理由を私は理解していないと、一部ではありません。 私が使用レンダリングコードは、(この例では私は、各次元の最上位層を描いてい注)である:

/// <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); 
     } 

Iの後forループネストされた第3の層を作成する、異なるアプローチを使用してみました最初の1つで、私は最初のループの上の面を描画し、2番目のループのエッジのハイライトを維持します(私は知っている、これは非効率的で、私はおそらく、それぞれのタイルを描画するメソッド呼び出しを避ける必要があります単に今のところそれを働かそうとしている)。

結果は何とか優れているが、それでも予想、トップ行として機能していないが不足している、参照画像:

alt text

なぜ私はこの問題を抱えているの任意のアイデア?最初のアプローチでは、ある種のz戦闘かもしれませんが、私は正確な順序でスプライトを描画していますので、すでにそこにあるものを上書きしないでください。

おかげでみんな

+0

スケーリングを行っていますか? –

答えて

1

おっと、私はばかだよ:)私はSpriteBatch.begin(SpriteSortMode.BackToFront)でバッチを開始しましたが、私は描画でZ値を使用しませんでした。 SpriteSortMode.Deferredを使用してください。今はうまくいきます。みんな、ありがとう!

0

は、1つのまたは2ピクセルで、あなたの送信元と送信先の長方形のサイズを微調整してください。私は、これらの四角形がレンダリングされる領域の一種のアウトライン(outline)と一種のオフ・バイ・ワンの問題として扱われる方法と関係があることを疑っています。これは専門家のアドバイスではなく、ただの仲間のコーダーの直感です。

0

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

どのようにスケールするかはわかりませんが、可能な限り丸めを避けてください(特にdrawTop()メソッド内)。あなたがいくつかの位置/座標のチャンスを回すたびに、あなたはエラー/ランダムオフセットを増やすかもしれません。整数の代わりにdouble(またはより良い:float)座標を使用するようにしてください。

+0

今私は1:1スケールを使用していますが、私がそれを変更すると、特定のスケールでいくつかのアーティファクトを実行します(つまり、ブロックは特定のラインのピクセルを「見逃す」)。また、矩形の原点はint値にしか設定できないようですね。 – Marco83

+0

決して使用しないでください(大部分はプレーンDirectXとOpenGLに集中しています)。ただし、画面座標/ピクセルを使用する場合は整数で構いません。それらを計算している間にラウンドしないでください(それらを渡す前に)。 – Mario

関連する問題