使用Monogame绘制平铺地图

3

我一直在尝试实现一个能够让我绘制瓷砖文件 (.tmx) 内部瓷砖的函数。我已经找了一些代码,有点可行但是会拉伸瓷砖。这是我找到并稍加编辑的代码

private void DrawLayer(int index, SpriteBatch batch) {
        for (var i = 0; i < Map.Layers[index].Tiles.Count; i++) {
            //Get the identification of the tile
            int gid = Map.Layers[index].Tiles[i].Gid;

            // Empty tile, do nothing
            if (gid == 0) { }
            else {
                int tileFrame = gid - 1 ;
                int column = tileFrame % (tileset.Width / tileWidth);
                int row = tileFrame / (tileset.Height / tileHeight);

                float x = (i % Map.Width) * Map.TileWidth;
                float y = (float)Math.Floor(i / (double)Map.Width) * Map.TileHeight;

                //Put all the data together in a new rectangle
                Rectangle tilesetRec = new Rectangle(tileWidth * column, tileHeight * row, tileWidth, tileHeight);

                //Draw the tile that is within the tilesetRec
                batch.Draw(tileset, new Rectangle((int)x, (int)y, tileWidth, tileHeight), tilesetRec, Color.White);
            }
        }
    }

你显然有错误的tileWidth和tileHeight。 - wingerse
不,那些实际上是正确的。 - Blapple
1个回答

5
MonoGame.Extended库支持加载和渲染Tiled(.tmx)地图。它是开源的,如果您想了解它的工作原理,可以查看它的代码。 图层渲染代码支持不同类型的地图(正交、等角线),不同的渲染顺序(右下、右上、左下、左上)和多个图块集,因此它不会像你的代码一样被简化为单个方法。
如果您提取相关代码的话,可能会得到类似于这样的东西:
for (var y = 0; y < layerHeight; y++)
{
    for (var x = 0; x < layerWidth; x++)
    {
        var region = tile.Id == 0 ? null : _regions[tile.Id];

        if (region != null)
        {
            var tx = tile.X * _map.TileWidth;
            var ty = tile.Y * _map.TileHeight;
            var sourceRectangle = region.Bounds;
            var destinationRectangle = new Rectangle(tx, ty, region.Width, region.Height);

            _spriteBatch.Draw(region.Texture, destinationRectangle, sourceRectangle, Color.White);
        }
    }
}

当然,还有一些缺失的部分,比如在加载瓷砖集时创建的纹理区域字典。
_regions = new Dictionary<int, TextureRegion2D>();

for (var y = Margin; y < texture.Height - Margin; y += TileHeight + Spacing)
{
    for (var x = Margin; x < texture.Width - Margin; x += TileWidth + Spacing)
    {
        _regions.Add(id, new TextureRegion2D(Texture, x, y, TileWidth, TileHeight));
        id++;
    }
}

纹理区域的定义实际上是什么。

public class TextureRegion2D
{
    public Texture2D Texture { get; protected set; }
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Width { get; private set; }
    public int Height { get; private set; }
    public Rectangle Bounds { get { return new Rectangle(X, Y, Width, Height); } }
}

请记住,我大部分代码都是从MonoGame.Extended中复制粘贴而来的。 它不会完全按照这里所写的工作,但如果您想编写自己的Tiled渲染代码,我认为我已经提供了足够的细节来解释其他所有变量的作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接