2010-11-30 3 views
0

В настоящее время я работаю над прототипом игры XNA. Я пытаюсь достичь изометрического представления игрового мира (или это отографическое? Я не уверен, какой правильный термин для этой проекции - см. Рисунки). Мир должен создать мир на основе плитки из кубических плит (например, похож на мир Minecraft), и я пытаюсь сделать его в 2D с помощью спрайтов.Проблема с изометрической изоляцией XNA

Итак, у меня есть лист спрайта с верхней поверхностью куба, лицевой стороной и стороной (видимая сторона). Я рисую плитки, используя 3 отдельных вызова drawSprite, один для верхнего, один для стороны, один для фронта, используя прямоугольник источника, чтобы выбрать лицо, которое я хочу рисовать, и прямоугольник назначения, чтобы установить положение на экране в соответствии с к формуле для преобразования из трехмерных мировых координат в изометрическую (орфографическую?).

(образец спрайт: 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); 
     } 

Я попытался с помощью другого подхода, создания второго яруса 3-вложенными для цикла после того, как первый, поэтому я держу верхнюю грань чертежа в первом цикле и краю выделения во втором цикле (я знаю, это неэффективно, я также, вероятно, не должен иметь вызов метода для каждой плитки, чтобы нарисовать его, но я просто пытаюсь заставить его работать сейчас).

Результаты как-то лучше, но по-прежнему не работает, как ожидалось, верхних рядах отсутствуют, см фото:

alt text

Любая идея, почему я с этой проблемой? В первом подходе это может быть своего рода z-борьба, но я рисую спрайты в точном порядке, поэтому они не должны переписывать то, что уже есть?

Спасибо всем

+0

Вы делаете любое масштабирование? – 2010-11-30 22:33:25

ответ

1

О, извините, ребята, я идиот :) Я начал партию с помощью SpriteBatch.begin (SpriteSortMode.BackToFront), но я не использовал никакого значения z в розыгрыше. Я должен был использовать SpriteSortMode.Deferred! Сейчас он работает нормально. Всем спасибо!

0

Try настройки размеров вашего источника и назначения прямоугольников 1 или 2 пикселя. У меня есть подозрительное подозрение, что это связано с тем, как эти прямоугольники обрабатываются как «контуры» области, которую нужно визуализировать, и своего рода проблема «один за другим». Это не экспертные советы, а просто интуиция кодера.

0

Выглядит как проблема с подпиксельной точностью или масштабированием. Также попробуйте обеспечить, чтобы ширина/высота текстуры/плитки составляла 2 (32, 64, 128 и т. Д.), Что могло бы сделать эффект менее плохим. С этих картин действительно сложно сказать.

Я не знаю, как и если вы масштабируете все, но вы должны стараться избегать округления везде, где это возможно (особенно в вашем методе drawTop()).Каждый раз, когда вы выполняете некоторые шансы на положение/координаты, вы можете увеличить ошибки/случайные смещения. Попытайтесь использовать двойные (или лучше: float) координаты вместо целого.

+0

Прямо сейчас я использую шкалу 1: 1, если меняю ее, я запускаю некоторые артефакты в некоторых конкретных масштабах (т. Е. Блоки пропускают пиксель в заданной строке), но это нормально. Также кажется, что начало прямоугольника может быть установлено только на значение int? – Marco83 2010-11-30 22:59:15

Смежные вопросы