I'm currently trying to load game objects from a Tiled (Tiled map editor) map file into a game engine I'm making in C#. I'm using TiledSharp (Link to github here). It uses a dictionary to hold properties about each individual tile (or 'game object') I'm trying to load. But for some reason I get an error when I loop through the properties, and I also get an error if I check if it's null
Here's a snippet of the code I'm using:
for (int l = 0; l < tmxMap.Tilesets[k].Tiles.Count; l++)
// This line throws an error
if (tmxMap.Tilesets[k].Tiles[l].Properties != null)
// and if I remove the above line, this line throws an error
for (int m = 0; m < tmxMap.Tilesets[k].Tiles[l].Properties.Count; m++)
The error I get says The given key was not present in the dictionary. But... I'm not even checking for a key.
Am I missing something?
Any help would be appreciated.
The error I get says The given key was not present in the dictionary. But... I'm not even checking for a key.
Yes you are checking for a key. This is your code:
if (tmxMap.Tilesets[k].Tiles[l].Properties != null)
You are checking for Tilesets
with key k
and then checking Tiles
with key l
. If the Tilesets
does not contain an item with key k
, you will get that error. The same is true for Tiles
with key l
.
You can do the following when working with dictionaries:
Option 1
The lookup is performed twice: once to see if the item exists, and then a second time to get the value:
var items = new Dictionary<string, string>();
items.Add("OneKey", "OneValue");
if(items.ContainsKey("OneKey"))
{
var val = items["OneKey"];
}
Option 2
And here is another approach where the lookup is performed once:
string tryVal;
if (items.TryGetValue("OneKey", out tryVal))
{
// item with key exists so you can use the tryVal
}
As far as I can see in your code I think that Tiles is a Dictionary and when you try to iterate by tmxMap.Tilesets[k].Tiles[l]
it throws error because it searches for key l, not for the l-element.
You can try tmxMap.Tilesets[k].Tiles[tmxMap.Tilesets[k].Tiles.Keys.ElementAt(l)]
You are trying to get a value based on keys k
,l
.
if (tmxMap.Tilesets[k].Tiles[l].Properties != null)
statement is basically getting the value corresponding to the k
key in Tilesets
dictionary. If Tilesets
dictionary doesn't contain a value for the key k
, an exception will be thrown. Also if there is no value corresponding to the l
key, in Tiles dictionary, exception will be thrown.
You can use TryGetValue
extension method, which will give you the value if the item was found.
TileSet ts = null;
if(tmxMap.Tilesets.TryGetValue(k, out ts)
{
for (int l = 0; l < ts.Tiles.Count; l++)
{
Tiles tl = null;
if(ts.TryGetValue(l,out tl)
{
if (tl.Properties != null)
{
for (int m = 0; m < tl.Properties.Count; m++)
{
//Do something
}
}
}
}
}