В настоящее время я работаю над прототипом игры XNA. Я пытаюсь получить изометрический вид игрового мира (или это отографический? Я не уверен, какой термин подходит для этой проекции - см. Рисунки). Мир должен представлять собой мир, основанный на плитках, состоящий из кубических плиток (например, похожий на мир Minecraft), и я пытаюсь визуализировать его в 2D с помощью спрайтов.
Итак, у меня есть лист спрайтов с верхней гранью куба, передней гранью и боковой (видимой стороной) гранью. Я рисую плитки, используя 3 отдельных вызова drawSprite, один для верхней части, один для стороны, один для передней части, используя исходный прямоугольник, чтобы выбрать лицо, которое я хочу нарисовать, и целевой прямоугольник, чтобы установить положение на экране в соответствии с в формулу для преобразования трехмерных мировых координат в изометрические (орфографические?).
(образец спрайта: )
Это работает хорошо, пока я рисую лица, но если я попытаюсь нарисовать четкие края каждого блока (в соответствии с сеткой плитки), я могу увидеть, что я получаю случайный образец рендеринга, в котором некоторые линии перезаписываются самим лицом и некоторые нет.
Обратите внимание, что для моего представления мира 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);
}
Я попытался использовать другой подход, создав второй трехуровневый вложенный цикл for после первого, поэтому я сохраняю рисунок верхней грани в первом цикле и выделение края во втором цикле (я знаю, это неэффективно, я должен также, вероятно, избегайте вызова метода для каждой плитки, чтобы нарисовать ее, но я просто пытаюсь заставить ее работать).
Результаты несколько лучше, но все еще не работают должным образом, верхние строки отсутствуют, см. Рисунок:
Есть идеи, почему у меня эта проблема? При первом подходе это может быть своего рода z-борьба, но я рисую спрайты в точном порядке, так что не должны ли они перезаписывать то, что уже есть?
Всем спасибо