0

我一直在尝试编写一个 Tilemap 引擎,它使用一组 Tile 类来存储信息。这些 Tile 类存储 8 条信息(所有数字),包括纹理索引和工件索引,但是在保存和加载这些数组时可能需要很长时间,尤其是加载可能需要几分钟才能加载更大尺寸的数组,例如 100x100。我目前正在使用文本文件来保存信息,用空格分隔不同的 Tiles,并使用逗号分隔这些 Tiles 的不同信息,我使用 StreamReaders 和 StreamWriters 来读取这些信息。

    public void Load()
    {
        try
        {
            TextReader TR = new StreamReader("C:/Users/Cogythea/Documents/Programming TextFiles/TileMap.tilemap");
            TR.Close();


            StreamReader reader = new StreamReader("C:/Users/Cogythea/Documents/Programming TextFiles/TileMap.tilemap");
            List<string[]> stringLists = new List<string[]>();

            int arrayArea;

            int lineLength = 0;
            int arrayHeight = 0;

            int width;

            string line;
            while ((line = reader.ReadLine()) != null)
            {
                lineLength = line.Length;
                arrayHeight++;

                stringLists.Add(line.Split(' '));
            }

            arrayArea = lineLength * arrayHeight;




            for (int y = 0; y < lineLength; y++)
            {
                for (int x = 0; x < arrayHeight; x++)
                {
                    try
                    {
                        string currentLine = stringLists[x][y].ToString();

                        List<string[]> currentLineSections = new List<string[]>();
                        currentLineSections.Add(currentLine.Split(','));

                        Map[x, y].textureIndex = Convert.ToInt16(currentLineSections[0][0].ToString());
                        Map[x, y].accessoryIndex = Convert.ToInt16(currentLineSections[0][1].ToString());


                        if (currentLineSections[0][2].ToString() == "1")
                            Map[x, y].colliding = true;
                        else
                            Map[x, y].colliding = false;


                        if (currentLineSections[0][3].ToString() == "1")
                            Map[x, y].startLocation = true;
                        else
                            Map[x, y].startLocation = false;


                        if (currentLineSections[0][4].ToString() == "1")
                            Map[x, y].portal = true;
                        else
                            Map[x, y].portal = false;



                        if (currentLineSections[0][5].ToString() == "1")
                            Map[x, y].portalExit = true;
                        else
                            Map[x, y].portalExit = false;


                        Map[x, y].portalNumber = Convert.ToInt16(currentLineSections[0][6].ToString());

                        Map[x, y].portalDestination = new Vector2(Convert.ToInt16(currentLineSections[0][7].ToString()), Convert.ToInt16(currentLineSections[0][8].ToString()));

                    }
                    catch (Exception e)
                    {

                    }
                }
            }



            reader.Close();
        }

        catch (Exception)
        {
        }
    }

    public void Save()
    {
        try
        {
            TextReader TR = new StreamReader("C:/Users/Cogythea/Documents/Programming TextFiles/TileMap.tilemap");
            TR.Close();
        }

        catch (Exception)
        {
            FileStream create = File.Create("C:/Users/Cogythea/Documents/Programming TextFiles/TileMap.tilemap");
            create.Close();
        }


        StreamWriter writer = new StreamWriter("C:/Users/Cogythea/Documents/Programming TextFiles/TileMap.tilemap");
        for(int x = 0; x < Map.GetLength(0); x++)
        {
            for (int y = 0; y < Map.GetLength(1); y++)
            {
                writer.Write(Map[x, y].textureIndex.ToString() + ",");
                writer.Write(Map[x, y].accessoryIndex.ToString() + ",");

                if(Map[x,y].colliding)
                    writer.Write("1,");
                else
                    writer.Write("0,");

                if (Map[x, y].startLocation)
                    writer.Write("1,");
                else
                    writer.Write("0,");


                if (Map[x, y].portal)
                    writer.Write("1,");
                else
                    writer.Write("0,");


                if (Map[x, y].portalExit)
                    writer.Write("1,");
                else
                    writer.Write("0,");

                writer.Write(Map[x, y].portalNumber.ToString() + ",");

                writer.Write(Map[x, y].portalDestination.X.ToString() + ",");
                writer.Write(Map[x, y].portalDestination.Y.ToString() + ",");

                writer.Write(" ");
            }
            writer.WriteLine();
        }
        writer.Close();
    }

我一直在互联网上寻找替代方法,我发现对用于存储信息的 XML 文件有压倒性的支持。现在,我有两个关于这个的问题。一,我一直在使用的代码教程(http://msdn.microsoft.com/en-us/library/bb203924.aspx)说要为 IAsyncResult 使用 StorageDevice,但是当我声明它时,Visual Studio 会带来两个问题之一:如果我不初始化它,它说它不存在(如你所料),但是当我初始化它时 -

    StorageDevice device = new StorageDevice();

我收到错误“'Microsoft.Xna.Framework.Storage.StorageDevice' 类型没有定义构造函数”,尽管它没有告诉我括号中需要任何东西,那么我该如何让它工作?对此的任何帮助将不胜感激。我的第二个问题是是否有任何其他替代方案,或者即使我的原始方法是正确的但需要改进。我在业余时间已经尝试解决这个问题两周了,所以我真的很感激任何帮助。谢谢。

4

1 回答 1

0

对于 tilemap,我永远不会使用 XML 存储。围绕基本上是 2D 的东西,它有太多的“控制语法”。

一个简单的文本文件,每一行都是地图中的一行,二进制文件似乎更合乎逻辑甚至更好。

但是为了使其易于阅读和维护,您可以制作一个“解析器”来读取您的 XML 文件,将它们解析为您自己的二进制格式,然后将二进制输出保存为您自己的图块/地图格式。

然后你只需要一个“地图/瓦片加载器”来读取你的这个解析/压缩格式。

= 可维护性和速度。

大多数语言都是一样的,你用“人类可读的语言”编写它们,然后将它们编译成“汇编器/二进制操作码”。

于 2014-03-29T00:36:33.233 回答