I am trying to build a JSON tile map importer for the content pipeline of Monogame but I'm having difficulty doing so. I have been following this tutorial and got something... But now it appears my entire JSON level cannot be loaded since it has an array-based structure, and my code expects an object, here is my level file:
[
[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,2,2,2,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]
]
And below are the custom content pipeline classes I made:
public class MapFile
{
private MapFile map;
public MapFile(MapFile map)
{
this.map = map;
}
public int[,] MapContent { get; set; }
}
[ContentImporter(".json", DefaultProcessor = "TileMapProcessor",
DisplayName = "TileMap Importer")]
public class MapImporter : ContentImporter<MapFile>
{
public override MapFile Import(string filename, ContentImporterContext context)
{
context.Logger.LogMessage("Importing Map file: {0}", filename);
using (StreamReader streamReader = new StreamReader(filename))
{
JsonSerializer serializer = new JsonSerializer();
return (MapFile)serializer.Deserialize(streamReader, typeof(MapFile));
}
}
}
public class MapReader : ContentTypeReader<MapFile>
{
protected override MapFile Read(ContentReader input, MapFile existingInstance)
{
string json = input.ReadString();
StreamReader reader = new StreamReader(json);
JsonSerializer serializer = new JsonSerializer();
MapFile mapFile = (MapFile)serializer.Deserialize(reader, typeof(MapFile));
MapFile map = input.ContentManager.Load<MapFile>(mapFile.MapContent.ToString());
return new MapFile(map);
}
}
The problem: As I said above, I get the following error at the content pipeline app:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current > JSON array (e.g. [1,2,3]) into type 'my class' because the type requires a > JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. >{"name":"value"}) or change the deserialized type to an array or a type >that implements a collection interface (e.g. ICollection, IList) like List > that can be deserialized from a JSON array. JsonArrayAttribute can also be > added to the type to force it to deserialize from a JSON array.
Changing the type from int[,]
to List<List<int>>
would be easy, but I have the following code to generate visual representation of the map files:
public void Generate(MapFile map, int size)
{
for (int x = 0; x < map.MapContent.GetLength(1); x++)
{
for (int y = 0; y < map.MapContent.GetLength(0); y++)
{
int number = map.MapContent[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;
}
}
}
So that is what I am using. I hope you can help me, I've got everything right, including the collision so loading my maps from XNB files is the last thing I need to do. Thanks in advance! Edit: new level format:
{
"Name": "My Level",
"MapContent":
[
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,2,2,2,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
]
}