【问题标题】:XNA isometric tiles rendering issueXNA 等距瓷砖渲染问题
【发布时间】:2010-11-30 22:26:41
【问题描述】:

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

所以我有一个包含立方体顶面、正面和侧面(可见面)的精灵表。我使用 3 个单独的 drawSprite 调用来绘制图块,一个用于顶部,一个用于侧面,一个用于正面,使用源矩形选择我要绘制的面,使用目标矩形设置屏幕上的位置转换为从 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);   
        }

我尝试使用不同的方法,在第一个循环之后创建第二个 3 层嵌套 for 循环,因此我在第一个循环中保留顶面绘图,在第二个循环中保留边缘突出显示(我知道,这是低效的,我也应该避免为每个图块调用方法来绘制它,但我现在只是想让它工作)。

结果在某种程度上更好,但仍然无法按预期工作,缺少顶部行,见图:

知道我为什么会遇到这个问题吗?在第一种方法中,它可能是一种 z-fighting,但我正在以精确的顺​​序绘制精灵,所以它们不应该覆盖已经存在的内容吗?

谢谢大家

【问题讨论】:

    标签: xna tiles sprite isometric


    【解决方案1】:

    哇,对不起,伙计们,我是个白痴 :) 我用 SpriteBatch.begin(SpriteSortMode.BackToFront) 开始批处理,但我没有在抽奖中使用任何 z 值。 我应该使用 SpriteSortMode.Deferred!现在工作正常。谢谢大家!

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        看起来像亚像素精度或缩放问题。还要尝试确保您的纹理/平铺宽度/高度是 2 的幂(32、64、128 等),因为这也可以使效果不那么糟糕。光看这些照片真的很难分辨。

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

        【讨论】:

        • 现在我使用的是 1:1 比例,如果我改变它,我会在某些特定比例下运行一些工件(即块“错过”给定行中的一个像素),但其他方面没问题.好像也是矩形原点只能设置成int值吧?
        • 从未使用过它(主要集中在普通的 DirectX 和 OpenGL),但如果它需要屏幕坐标/像素,整数是可以的。只是在计算时不要四舍五入(在通过它们之前)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-22
        • 2021-05-23
        • 1970-01-01
        • 2013-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多