我目前正在开发 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,但我正在以精确的顺序绘制精灵,所以它们不应该覆盖已经存在的内容吗?
谢谢大家