Рисование изометрических листов - PullRequest
2 голосов
/ 23 декабря 2010

Я работал над рисованием изометрической карты в C # / XNA Game Studio, и хотя я довольно далеко, это выглядит не совсем правильно, и мне было интересно, может ли кто-нибудь помочь.

Вот код, который у меня есть для рисования карты:

public void Draw(SpriteBatch theBatch, int drawX, int drawY)
    {

        if ((drawY % 2 == 0))
            theBatch.Draw(tileTexture, new Rectangle((drawX * width), (drawY * length / 2), width, length), Color.White);
        else
            theBatch.Draw(tileTexture, new Rectangle(((drawX * width) + (width / 2)), (drawY * length / 2), width, length), Color.White);
    }

Код в этом методе действует так, как если бы он был внутри вложенного цикла for, рисуя слева направо, сверху вниз. Когда значение y нечетно, строка сдвигается, чтобы соответствовать, однако это выглядит немного не так.

Это полученный результат для карты 8x5:

http://imgur.com/xpDRU.png

Как вы можете видеть, это выглядит не совсем правильно, и я не уверен, связано ли это с математикой в ​​моем коде, или это связано с порядком, в котором все прорисовывается. Я очень плохо знаком с C # и работаю со спрайтами, поэтому любая помощь будет принята с благодарностью.

Поскольку это может быть полезно, вот другие соответствующие части кода, которые рисуют карту.

Весь класс плиток:

public class Tile
{
    // Dimension variables
    int height;
    int width;
    int length;

    String type;
    Texture2D tileTexture;
    Vector2 coordinates;

    /// 
    /// Tile Constructor
    /// 
    public Tile(ContentManager theContent, String theType, Vector2 theCoordinates)
    {
        width = 68;
        length = 46;

        type = theType;
        coordinates = theCoordinates;

        // Sets the right texture to the texture ref
        if (theType == "grass")
            tileTexture = theContent.Load<Texture2D>(@"Tiles\iso_grass");
    }

    /// 
    ///  Draws the tile at the given location
    /// 
    public void Draw(SpriteBatch theBatch, int drawX, int drawY)
    {

        if ((drawY % 2 == 0))
            theBatch.Draw(tileTexture, new Rectangle((drawX * width), (drawY * length / 2), width, length), Color.White);
        else
            theBatch.Draw(tileTexture, new Rectangle(((drawX * width) + (width / 2)), (drawY * length / 2), width, length), Color.White);
    }


}

Класс TileRow, который содержит один ряд плиток.

public class TileRow
{
        public List<Tile> Row = new List<Tile>();
        public int rowLength;

        public TileRow(int theLength, int yIndex, ContentManager theContent)
        {
            rowLength = theLength;
            Tile thisTile;

            // Here the tiles are created and added to the row
            for (int x = 0; x < rowLength; x++)
            {
                thisTile = new Tile(theContent, "grass", new Vector2(x, yIndex));
                Row.Add(thisTile);
            }
        }

        /// 
        /// Draw -- invokes the draw method of each tile in the row
        /// 
        public void DrawRow(SpriteBatch theBatch, int currentY)
        {
            for (int x = 0; x < rowLength; x++)
            {
                Row[x].Draw(theBatch, currentY, x);
            }
        }
    }
}

и класс MapStruct, который содержит все строки

public class MapStruct
{

    public List<TileRow> allRows = new List<TileRow>();
    int depth;

    // Constructor
    public MapStruct(ContentManager theContent, int theDepth, int rowLength)
    {
        depth = theDepth;
        TileRow thisRow;

        // Here we make a row of tiles for each level of depth
        for (int y = 0; y < depth; y++)
        {
            thisRow = new TileRow(rowLength, depth, theContent);
            allRows.Add(thisRow);
        }
    }

    ///
    /// Draw - this method invokes the draw method in each tile row, which then draws each tile
    ///
    public void DrawMap(SpriteBatch theBatch)
    {
        for (int y = 0; y < depth; y++)
        {
            allRows[y].DrawRow(theBatch, y);
        }
    }
}

Буду очень признателен за любую помощь в том, как я могу решить эту проблему, а также за советы, как я могу улучшить свой код!

Ответы [ 2 ]

1 голос
/ 23 декабря 2010

Похоже, ваш цикл добавляет немного к значению Y в каждой строке. Я нашел эту переменную в вашей функции Tile.

length = 46;

Я не проверял, но я считаю, что "длина" - это высота плитки? если так, попробуйте немного отрегулировать его. Возможно, вы забыли минус высоту плитки. Так что, если сторона плитки равна 6 пикселям, то длина смещения pr. строка только 40.

Также не забывайте рисовать сверху и снизу, поскольку ближайшая камера тайлов должна наноситься последней, чтобы создать иллюзию глубины.

0 голосов
/ 23 декабря 2010

Я считаю, что BerggreenDK прав, но ваш комментарий заставляет вас думать, что вы не поняли его ответ. Ваши плитки должны быть нарисованы со смещением Y, которое включает в себя только зеленые области поверхности «высота экрана». Итак, нарисуйте полный размер плитки, но сместите строки с длиной - 5 (где 10 - предполагаемое смещение, а 5 - половина, так как каждая строка должна быть смещена только на половину расстояния).

theBatch.Draw(tileTexture, new Rectangle((drawX * width), (drawY * (length) / 2), width, length - 5), Color.White);

... если я правильно понял параметры.

Кроме того, строки должны быть нарисованы сзади вперед, но они, кажется, нарисованы слева направо? Я не знаю XNA, поэтому не могу показать код, чтобы это исправить ... когда я приглядываюсь, некоторые плитки подряд "дальше" перетягиваются плиткой "ближе". Я не знаю XNA и не понимаю, как определяется порядок рисования, поэтому не могу предложить решение этой проблемы ...

...