Drawing Isometric Tilemaps

穿精又带淫゛_ 提交于 2019-12-11 01:17:40

问题


I've been working on drawing an isometric map with C# / XNA Game Studio, and while I've gotten pretty far it doesn't look quite right and I was wondering if anybody can help.

Here's the code I have for drawing the map:

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);
    }

The code within this method acts as if it were inside a nested for loop, drawing left to right, top to bottom. When the y-value is odd, the row is shifted over to fit, however it looks a bit off.

This is the produced output for an 8x5 map:

As you can see, it doesn't quite look right, and I'm not sure if its an issue with the math in my code, or if it has to do with the order everything is being drawn in. I'm very new to C# and working with sprites, so any help would be greatly appreciated.

Because it might be helpful, here is the other relevant parts of code which draw the map.

The entire Tile Class:

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);
    }


}

The TileRow class, which holds one row of tiles.

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);
            }
        }
    }
}

and the MapStruct class, which holds all the rows

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);
        }
    }
}

Any help on how I could fix this issue, as well as advice on how I could improve my code would be greatly appreciated!


回答1:


Looks like your loop adds a little to much to the Y on each row. I found this variable in your Tile function.

length = 46;

I havent checked, but I believe "length" is the height of the tile? if so, try ajusting it a bit. Perhaps, you've forgotten to minus the height of the tile. So if the side of the tile is like 6 pixels, then the length for offset pr. row is only 40.

Also remember to plot from top and down, since the tiles nearest camera has to be plotted last, to make the depth illusion.




回答2:


I beleive BerggreenDK is right, but your comment make it seem you misunderstood his answer. Your tiles need to be drawn at an Y offset that only includes the green surface areas "screen height". So, draw the full tile size, but offset the rows with length - 5 (Where 10 is the estimated offset and 5 is half that, as each row should be offset by only half the distance).

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

...if I got the parameters right.

Also, the rows need to be drawn from back to front, but they seem to be drawn from left to right? I don't know XNA, so can't show code to fix that...when I look closely some tiles in a row "further away" is over-drawn by a tile "closer". I don't know XNA and don't get how the drawing order is determined, so can't offer a fix for that...



来源:https://stackoverflow.com/questions/4515264/drawing-isometric-tilemaps

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!