XNA等轴测图块渲染问题

XNA等轴测图块渲染问题,xna,tiles,sprite,isometric,Xna,Tiles,Sprite,Isometric,我目前正在开发一款XNA游戏原型。我试图获得一个游戏世界的等距视图(或者它是otherographic的??我不确定哪个是这个投影的正确术语-参见图片)。 这个世界应该是一个由立方体瓷砖组成的基于瓷砖的世界(例如,类似于Minecraft的世界),我正在尝试使用精灵在2D中渲染它 所以我有一个精灵表,上面有立方体的顶面,前面和侧面(可见的一面)。我使用对drawSprite的3个单独调用绘制瓷砖,一个用于顶部,一个用于侧面,一个用于前部,使用源矩形选择我要绘制的面,使用目标矩形根据公式设置屏幕上

我目前正在开发一款XNA游戏原型。我试图获得一个游戏世界的等距视图(或者它是otherographic的??我不确定哪个是这个投影的正确术语-参见图片)。 这个世界应该是一个由立方体瓷砖组成的基于瓷砖的世界(例如,类似于Minecraft的世界),我正在尝试使用精灵在2D中渲染它

所以我有一个精灵表,上面有立方体的顶面,前面和侧面(可见的一面)。我使用对drawSprite的3个单独调用绘制瓷砖,一个用于顶部,一个用于侧面,一个用于前部,使用源矩形选择我要绘制的面,使用目标矩形根据公式设置屏幕上的位置,以从3D世界坐标转换为等轴测(正交?)

(雪碧样品: )

只要我画面,这个效果就很好,但是如果我尝试画每个块的细边(根据平铺网格),我可以看到我得到一个随机的渲染模式,其中一些线被面本身覆盖,而一些线没有覆盖

请注意,对于我的世界表示,X是从左到右,Y是从屏幕内部到屏幕外部,Z是从上到下

在本例中,我仅处理顶面边。以下是我得到的(图片):

我不明白为什么有些行显示,有些行不显示。 我使用的渲染代码是(注意,在本例中,我只绘制每个维度中最顶层的层):

//
///吸引世界
/// 
/// 
公共作废抽签(SpriteBatch SpriteBatch)
{
Texture2D tex=null;
//画瓷砖
对于(int z=numBlocks-1;z>=0;z--)
{
对于(int y=0;y=0;x--)
{
myTextures.TryGetValue(myBlockManager.getBlockAt(x,y,z),out-tex);
如果(tex!=null)
{
//顶面
如果(z==0)
{
抽拉式车顶(spriteBatch、x、y、z、tex);
drawTop(spriteBatch、x、y、z、大纲图);
}
//正面
如果(y==numBlocks-1)
前拉丝(雪碧、x、y、z、tex);
//侧面
如果(x==0)
抽绳侧(spriteBatch、x、y、z、tex);
}
}
}
}
}
专用void吸顶(SpriteBatch SpriteBatch、int x、int y、int z、Texture2D tex)
{
int pX=偏移量x+(int)(x*纹理\u顶部\u x\u右侧+y*纹理\u侧面\u x);
int pY=OffsetY+(int)(y*纹理\顶部\ y+z*纹理\前部\ y);
topDestRect.X=pX;
topDestRect.Y=pY;
spriteBatch.Draw(特克斯、topDestRect、纹理、颜色、白色);
}
我尝试使用另一种方法,在第一个循环之后创建第二个嵌套的3层for循环,因此我在第一个循环中保留顶面绘制,在第二个循环中保留边高亮显示(我知道,这是低效的,我可能还应该避免对每个瓷砖进行方法调用来绘制它,但我现在只是尝试让它工作)

结果虽然有所改善,但仍然没有达到预期效果,缺少最上面的行,请参见图片:

知道我为什么会有这个问题吗?在第一种方法中,它可能是一种z-战斗,但我以精确的顺序绘制精灵,所以它们不应该覆盖已经存在的东西吗


谢谢大家

尝试将源矩形和目标矩形的大小调整1或2像素。我有一种隐秘的怀疑,这与这些矩形被处理为待渲染区域的“轮廓”的方式有关,并且有点像一个问题。这不是专家的建议,只是同事的直觉。

看起来像是亚像素精度或缩放问题。另外,请确保纹理/瓷砖宽度/高度为2的幂(32、64、128等),这样也可以使效果不那么糟糕。仅仅从这些照片很难分辨


我不知道如何/是否缩放所有对象,但应尽量避免四舍五入(尤其是在
drawTop()方法中)。每次你绕过一些位置/坐标的机会是好的,你可能会增加误差/随机偏移。尝试使用双精度(或更好的:浮点)坐标而不是整数。

哇,对不起,伙计们,我是个白痴:)我用SpriteBatch.begin(SpriteSortMode.BackToFront)开始批处理,但我在绘图中没有使用任何z值。
我应该用SpriteSortMode的。推迟!现在很好用。谢谢大家

现在我使用的是1:1比例,如果我改变它,我会在一些特定比例下运行一些工件(即,块“错过”给定行中的一个像素),但在其他方面没有问题。似乎矩形原点只能设置为int值?从未使用过它(主要集中在普通DirectX和OpenGL上),但如果它采用屏幕坐标/像素,整数也可以。只是在计算这些数据时(在通过它们之前)不要绕圈。
/// <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);   
        }