试图找到最有效的方式来存储和加载信息的磁贴地图游戏引擎

本文关键字:信息 加载 引擎 游戏 地图 有效 方式 存储 | 更新日期: 2023-09-27 18:10:14

我一直在尝试编写一个使用Tile类数组来存储信息的Tilemap引擎。这些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的存储设备,但当我声明它Visual Studio带来了两个问题之一:如果我不初始化它,它说它不存在(如你所期望的),但当我初始化它-

    StorageDevice device = new StorageDevice();

我得到错误"类型"Microsoft.Xna.Framework.Storage。StorageDevice"没有定义构造函数",尽管它没有告诉我括号中需要什么,那么我如何让它工作呢?任何帮助,这将是非常感激。我的第二个问题是,是否有任何其他替代方案,或者即使我原来的方法是正确的,但需要改进。我已经在我的业余时间断断续续地尝试解决这个问题两周了,所以我将非常感谢任何帮助。谢谢。

试图找到最有效的方式来存储和加载信息的磁贴地图游戏引擎

对于磁贴图,我永远不会使用XML存储。这是太多的"控制语法"围绕着基本上是2D的东西。

一个简单的文本文件,每一行都是映射中的一行,看起来更合乎逻辑,甚至更好,一个二进制文件。

但是为了使它易于阅读和维护,您可以创建一个"解析器"来读取您的XML文件,将它们解析成您自己的二进制格式,然后将二进制输出保存为您自己的tile/map格式。

那么你只需要一个"map/tile loader"来读取你的解析/压缩格式。

=可维护性和速度。

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