C# 绘制等轴测平铺图

C# 绘制等轴测平铺图,c#,xna,2d,isometric,C#,Xna,2d,Isometric,我一直在用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 *

我一直在用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地图的生成输出:

正如您所看到的,它看起来不太正确,我不确定这是否是我代码中的数学问题,或者它是否与绘制所有内容的顺序有关。我对C#和sprites非常陌生,因此非常感谢您的帮助

因为这可能会有所帮助,下面是绘制地图的代码的其他相关部分

整个瓷砖类别:

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


}
公共类平铺
{
//维度变量
内部高度;
整数宽度;
整数长度;
字符串类型;
纹理2D瓷砖结构;
矢量2坐标;
/// 
///平铺构造器
/// 
公共互动程序(内容管理器内容,字符串类型,向量2协调)
{
宽度=68;
长度=46;
类型=类型;
坐标=坐标;
//将右侧纹理设置为纹理参照
如果(类型==“草”)
tileTexture=内容加载(@“Tiles\iso_grass”);
}
/// 
///在给定位置绘制平铺
/// 
公共无效绘图(批处理、整数绘图、整数绘图)
{
如果((提款%2==0))
绘制(平铺纹理,新矩形((drawX*宽度),(drawY*长度/2),宽度,长度),颜色.白色);
其他的
batch.Draw(平铺纹理,新矩形((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);
            }
        }
    }
}
公共类TileRow
{
公共列表行=新列表();
公共整数行长;
公共TileRow(int长度、int索引、ContentManager内容)
{
行长=长度;
瓷砖;
//此时将创建平铺并将其添加到行中
对于(int x=0;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);
        }
    }
}
公共类映射结构
{
public List allRows=新列表();
智力深度;
//建造师
公共映射结构(ContentManager-theContent,int-theDepth,int-rowLength)
{
深度=深度;
TileRow thisRow;
//在这里,我们为每个深度级别制作一排瓷砖
对于(int y=0;y

任何关于我如何解决这个问题的帮助,以及关于我如何改进代码的建议都将不胜感激

看起来您的循环在每行的Y上增加了一点或更多。 我在Tile函数中找到了这个变量

length = 46;
我还没有检查,但我相信“长度”是指瓷砖的高度?如果是这样,试着调整一下。也许你忘了减去瓷砖的高度。因此,如果平铺的侧面像6个像素,那么偏移pr.行的长度只有40


还记得从上到下绘图,因为最近的相机必须最后绘制,才能产生深度错觉。

我相信BerggreenDK是对的,但你的评论让人觉得你误解了他的答案。您的平铺需要在Y偏移处绘制,该偏移仅包括绿色表面区域“屏幕高度”。因此,绘制完整的平铺大小,但偏移长度为-5的行(其中10是估计偏移量,5是估计偏移量的一半,因为每行应仅偏移距离的一半)

…如果参数正确的话


此外,行需要从后向前绘制,但它们似乎是从左向右绘制的?我不知道XNA,所以无法显示代码来修复此问题…当我仔细查看一行中的一些瓷砖时,“更远”被瓷砖“更近”覆盖。我不知道XNA,也不知道绘图顺序是如何确定的,因此无法提供解决方案…

是的,“长度”是文件的高度。调整变量的值没有帮助,但是在奇数行上从Y中减去4有点帮助,但看起来仍然不正确。(调整后)我现在也看到了最后一张照片。我想知道现在是不是瓷砖的“z指数”欺骗了你?关于磁贴大小,在旧的“位图”时代,我们使用“二进制”大小获得了最佳性能。这是32,64,或者其他用8位除的宽度。如果你用一个画图程序,把它们放在一起,你会看到一个很好的图案形成。但是你最近一篇文章的问题并不是因为篇幅太大。我相信这就是算法用Z索引创建它们的方式(就像在Flash中一样)。不确定,因为我对XNA APICan了解不够,您能向我们解释一下您发布的算法吗?你是按行还是按对角线阅读瓷砖贴图?我已经改变了从下到上绘制的循环,并根据你的建议更改了瓷砖绘制线
theBatch.Draw(tileTexture, new Rectangle((drawX * width), (drawY * (length) / 2), width, length - 5), Color.White);