【问题标题】:Monogame layers drawing over each other - why?Monogame 层相互重叠 - 为什么?
【发布时间】:2019-12-12 17:05:26
【问题描述】:

我是 Monogame 和 C# 的新手。我正在尝试使用TiledSharp 在屏幕上呈现测试平铺地图。但是,当我尝试绘制多个图层时,它们显然会循环并相互叠加。

这是我的draw方法代码:

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);



        // TODO: Add your drawing code here
        spriteBatch.Begin(sortMode: SpriteSortMode.FrontToBack, blendState: BlendState.AlphaBlend, samplerState: SamplerState.PointClamp, null, null, null,
            Matrix.CreateScale(6.0f)); 

        for (currentTileLayer=0; currentTileLayer < easyMap.TileLayers.Count; currentTileLayer++)


        {
            Console.WriteLine(easyMap.TileLayers[currentTileLayer].Name.ToString());


            for (var i = 0; i < easyMap.TileLayers[currentTileLayer].Tiles.Count; i++)
            {

                int gid = easyMap.TileLayers[currentTileLayer].Tiles[i].Gid;

                // empty tile, do nothing
                // gid => global id of tile
                if (gid == 0)
                {
                }
                else
                {
                    int tileFrame = gid - 1;
                    int column = tileFrame % tilesetTilesWide;
                    int row = (int)Math.Floor((double)tileFrame / (double)tilesetTilesWide);

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

                    Rectangle tileSetRec = new Rectangle(tileWidth * column, tileHeight * row, tileWidth, tileHeight);

                    spriteBatch.Draw(easyTileset, new Rectangle((int)x, (int)y, tileWidth, tileHeight), tileSetRec, Color.White);



                }



            }


        }


            spriteBatch.End();

        base.Draw(gameTime);

    }

我原来的地图是这样的:

当我运行代码时,它看起来像这样:

地图共有三层。我怎样才能修复我的循环?谢谢!

【问题讨论】:

    标签: c# monogame tiled


    【解决方案1】:

    您应该使用已排序的图层,因为 Tiled 非常支持它们。使用图层为您在地图设计方面提供了更多可能性。我还可以让你的角色隐藏在物体等后面。 在平铺中,如果需要在顶部创建几个图层,请先创建背景图层以避免错误的绘制顺序。

    一个简单的解决方案可能如下所示

    const int LAYER_BACKGROUNDLAYER = 0;
    const int LAYER_FRONTLAYER = 1;
    const int LAYER_TOPLAYER = 2;
    

    取决于您要使用的层数。

    然后您只需将要绘制的图层编号传递给您的 Draw-Method。通常从 0 到最大数。

    public void DrawLayer(int layer)
    {
        for (var j = 0; j < curMap.Layers[layer].Tiles.Count; j++)
        {
            int gid = curMap.Layers[layer].Tiles[j].Gid;
    
            if (gid == 0)
            { 
                //empty tile
            }
            else
            {
                //draw your tile
            }
        }
    }
    

    在这种情况下,“curMap”是您当前通过 curMap = new TmxMap(mapSource); 加载的 .tmx 文件 上面的绘制代码应该适合您的代码,因为我也是基于 TiledSharp 示例的;)

    【讨论】:

    • 谢谢!这很有帮助,同时使用 spritebatch 的层深度。我现在都在屏幕上看到了。
    【解决方案2】:

    我可能错了,但我认为您需要从后到前对图块进行排序。应该首先渲染底部的任何图块。

    for (currentTileLayer=0; currentTileLayer < easyMap.TileLayers.Count; currentTileLayer++)

    var orderedTiles = easyMap.TileLayers.OrderBy(t =&gt; t.Tile.Gid)替换你的TileLayers

    【讨论】:

    • 不幸的是,更改排序顺序并不会改变它的外观,但这可能是一个好主意。在您的第二部分中, TileLayers 实际上是 TmxList 并且它没有 OrderBy() 方法。
    • OrderBy 是一个 Linq 表达式。如果您不能在该对象上使用 Linq,那么您可以编写自己的排序方法。我仍然有点相信错误是渲染的顺序。如果是别的我想不出来。
    • 如果你足够勇敢,也可以制作自己的OrderBy() 方法作为扩展方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多