Monogame - 使用XML而不是JSON

时间:2016-05-22 12:06:58

标签: c# json xml serialization monogame

我正在研究游戏的关卡,所以我已经构建了这些类来阅读我的地图:

Tiles.cs:

protected Texture2D texture;
private Rectangle rectangle;
public Rectangle Rectangle
{
    get
    {
        return rectangle;
    }
    protected set
    {
        rectangle = value;
    }
}

private static ContentManager content;
public static ContentManager Content
{
    protected get
    {
        return content;
    }
    set
    {
        content = value;
    }
}

public void Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Draw(texture, rectangle, Game1.DefaultColor);
}

CollisionTiles.cs:

public CollisionTiles(int i, Rectangle newRectangle)
{
    texture = Content.Load<Texture2D>("Graphics/Tiles/tile_" + i);
    Rectangle = newRectangle;
}

Map.cs:

private List<CollisionTiles> collisionTiles;
public List<CollisionTiles> CollisionTiles
{
    get
    {
        return collisionTiles;
    }
}

private int width, height;
public int Width
{
    get
    {
        return width;
    }
}

public int Height
{
    get
    {
        return height;
    }
}

public Map()
{
    collisionTiles = new List<CollisionTiles>();
}

public void Generate(int[,] map, int size)
{
    for (int x = 0; x < map.GetLength(1); x++)
    {
        for (int y = 0; y < map.GetLength(0); y++)
        {
            int number = map[y, x];
            if (number > 0)
            {
                collisionTiles.Add(new CollisionTiles(number, new Rectangle(x * size, y * size, size, size)));
            }
            width = (x + 1) * size;
            height = (y + 1) * size;
        }
    }
}

public int[,] LoadLevelData(string filename)
{
    using (StreamReader streamReader = new StreamReader(filename))
    {
        JsonSerializer serializer = new JsonSerializer();
        return (int[,])serializer.Deserialize(streamReader, typeof(int[,]));
    }
}

public void Draw(SpriteBatch spriteBatch)
{
    foreach (CollisionTiles tile in collisionTiles)
    {
        tile.Draw(spriteBatch);
    }
}

level_1.json:

[
    [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
    [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 2, 2],
    [2, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 2, 2],
    [2, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 2, 2],
    [2, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2],
    [2, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
    [2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
    [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
    [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
]

我将Newtonsoft.Json包添加到我的项目中。但由于Monogame本身不支持JSON,而是 Content Pipeline 支持XML。如果我使用当前的级别加载方法运送我的游戏,我将被迫将其作为JSON文件而不是二进制XNB运送。这将使用户能够编辑他们喜欢的级别,我不希望这样。

那么如何将此代码转换为加载XML级别而不是JSON?你会采取什么方法来解决这个问题?我以前从未在我的项目中使用过Monogame的/ XNA的XML支持,但是将它用于我的关卡将是一个不错的开始。感谢所有帮助。

修改

用法

int defaultTileSize, level_number;
Map map;

// constructor:
defaultTileSize = 64;
level_number = 1;

// LoadContent()
int[,] levelData = map.LoadLevelData("level_" + level_number + ".json");
map.Generate(levelData, defaultTileSize);

// Draw()
map.Draw(spriteBatch);

2 个答案:

答案 0 :(得分:0)

我使用了以下xml

<?xml version="1.0" encoding="utf-8" ?>
<Root>
  <![CDATA[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1];
    [2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 2, 2];
    [2, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 2, 2];
    [2, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 2, 2];
    [2, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2];
    [2, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2];
    [2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2];
    [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2];
    [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]]]>
</Root>

然后阅读以下代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            List<List<int>> data = LoadLevelData(FILENAME);
        }
        public static List<List<int>> LoadLevelData(string filename)
        {
            List<List<int>> data = new List<List<int>>();
            XDocument doc = XDocument.Load(FILENAME);

            XElement root = doc.Element("Root");
            string array = root.Value;
            string[] rows = array.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string row in rows)
            {
                string line = row.Replace("[", "");
                line = line.Replace("]", "");
                List<int> newRow = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
                data.Add(newRow);
            }
            return data;
        }
    }
}

答案 1 :(得分:0)

这是应该有用的代码。找到以下网页:https://github.com/CartBlanche/MonoGame-Samples/blob/master/Storage/SaveGame.cs。以下代码在网页上的示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
        }

    }
    public class Map
    {
        public int[,] map { get; set; }

        public int[,] LoadLevelData(string filename)
        {
            using (XmlTextReader reader = new XmlTextReader(filename))
           {
               XmlSerializer xs = new XmlSerializer(typeof(Map));
               Map map = (Map)xs.Deserialize(reader);
               this.map = map.map;
               return map.map;
            }
        }
        public void SaveLevelData(string filename)
        {
            using (StreamWriter writer = new StreamWriter(filename))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Map));

                serializer.Serialize(writer, this.map);
                writer.Flush();
                writer.Close();
                writer.Dispose();
            }
        }
    }
}