C# Monogame-使用XML而不是JSON的平铺映射
我正在为我的游戏制作关卡,所以我建立了这些类来阅读我的地图: Tiles.cs:C# Monogame-使用XML而不是JSON的平铺映射,c#,json,xml,serialization,monogame,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 C
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);
}
public CollisionTiles(int i, Rectangle newRectangle)
{
texture = Content.Load<Texture2D>("Graphics/Tiles/tile_" + i);
Rectangle = newRectangle;
}
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);
}
}
[
[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]
]
CollisionTiles.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);
}
public CollisionTiles(int i, Rectangle newRectangle)
{
texture = Content.Load<Texture2D>("Graphics/Tiles/tile_" + i);
Rectangle = newRectangle;
}
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);
}
}
[
[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,而是其内容管道支持XML。如果我使用当前的关卡加载方法发布游戏,我将被迫以JSON文件而不是二进制XNB的形式发布它。这将使用户能够编辑他们喜欢的级别,我不希望这样
那么,如何将此代码转换为加载XML级别而不是JSON?你会采取什么方法来处理这个问题?我以前从未在我的项目中使用过Monogame/XNA的XML支持,但在我的级别中使用它将是一个很好的开始。感谢所有的帮助
编辑:
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);
}
public CollisionTiles(int i, Rectangle newRectangle)
{
texture = Content.Load<Texture2D>("Graphics/Tiles/tile_" + i);
Rectangle = newRectangle;
}
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);
}
}
[
[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]
]
用法:
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);
我使用了以下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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
列表数据=LoadLevelData(文件名);
}
公共静态列表LoadLevelData(字符串文件名)
{
列表数据=新列表();
XDocument doc=XDocument.Load(文件名);
XElement根=文档元素(“根”);
字符串数组=root.Value;
string[]rows=array.Split(新字符[]{';'},StringSplitOptions.RemoveEmptyEntries);
foreach(行中的字符串行)
{
字符串行=行。替换(“[”,”);
行=行。替换(“]”,“”);
List newRow=line.Split(new char[]{',},StringSplitOptions.removeMptyEntries)。选择(x=>int.Parse(x)).ToList();
data.Add(newRow);
}
返回数据;
}
}
}
我使用了以下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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
列表数据=LoadLevelData(文件名);
}
公共静态列表LoadLevelData(字符串文件名)
{
列表数据=新列表();
XDocument doc=XDocument.Load(文件名);
XElement根=文档元素(“根”);
字符串数组=root.Value;
string[]rows=array.Split(新字符[]{';'},StringSplitOptions.RemoveEmptyEntries);
foreach(行中的字符串行)
{
字符串行=行。替换(“[”,”);
行=行。替换(“]”,“”);
List newRow=line.Split(new char[]{',},StringSplitOptions.removeMptyEntries)。选择(x=>int.Parse(x)).ToList();
data.Add(newRow);
}
返回数据;
}
}
}
以下是应该有效的代码。找到以下网页:。下面是网页上的示例代码
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();
}
}
}
}
下面是应该可以工作的代码。找到以下网页:。下面是网页上的示例代码
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();
}
}
}
}
正如我在文章Monogame中所说,它有自己的内置XML序列化程序,当您将XML文件添加到内容管道中时,它将内置到一个二进制XNB文件中。从这里开始,您不应该编写自己的序列化程序,而应该使用已有的序列化程序。问题是我不知道如何做到这一点……正如我在《Monogame博文》中所说,Monogame有自己的内置XML序列化程序,当您将XML文件添加到内容管道时,它将内置到一个二进制XNB文件中。从这里开始,您不应该编写自己的序列化程序,而应该使用已有的序列化程序。问题是我不知道怎么做。。。