xamarincocossharp

cocossharp TilePropertiesForGID(info.Gid) always return null


I am using the CocoSharp.PCL.Shared Nuget version 1.6.2 and I am trying to get the tile property.

Here is the TileSet.tsx:

<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.2" tiledversion="1.2.1" name="wood_tileset" tilewidth="32" tileheight="32" tilecount="256" columns="16">
 <image source="wood_tileset.png" width="512" height="512"/>
 <tile id="68">
  <properties>
   <property name="IsTreasure" value="true"/>
  </properties>
 </tile>
</tileset>

The function I call to get my property:

void HandleCustomTilePropertyAt(int worldX, int worldY, CCTileMapLayer layer)
    {
        CCTileMapCoordinates tileAtXy = layer.ClosestTileCoordAtNodePosition(new CCPoint(worldX, worldY));

        CCTileGidAndFlags info = layer.TileGIDAndFlags(tileAtXy.Column, tileAtXy.Row);

        if (info != null && info.Gid == 68)
        {
            Dictionary<string, string> properties = null;

            try
            {
                properties = tileMap.TilePropertiesForGID(info.Gid);
            }
            catch
            {
                // CocosSharp 
            }

            if (properties != null && properties.ContainsKey("IsTreasure") && properties["IsTreasure"] == "true" )
            {
                layer.RemoveTile(tileAtXy);

                // todo: Create a treasure chest entity
            }
        }
    }

The problem is that : properties = tileMap.TilePropertiesForGID(info.Gid); always return null.

But if I break and look into the non-public variable, I can see the property of my tile : enter image description here

What am I doing wrong ?


Solution

  • I found a way to get my tile properties.

    1. Get a stream from the tileset.tsx
    2. Get the properties from a specifi tile id
    3. Create a function that parse the xml file tileset.tsx to make it works as cocossharp used to work.

    In Program.cs, Since it inherit from activity, I am able to open all assets :

    public class Program : AndroidGameActivity
    {
    
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
    
            CCApplication application = new CCApplication();
            application.ApplicationDelegate = new AppDelegate();
    
            this.SetContentView(application.AndroidContentView);
            this.LoadTileMapProperty();
    
            application.StartGame();
        }
    
        private void LoadTileMapProperty()
        {
            Settings.TileMapStream = new StreamReader(Assets.Open("Content/tileMap/wood_tileset.tsx"));
        }
    
    }
    

    in my GameLayer.cs :

     void HandleCustomTilePropertyAt(int worldX, int worldY, CCTileMapLayer layer)
        {
            CCTileMapCoordinates tileAtXy = layer.ClosestTileCoordAtNodePosition(new CCPoint(worldX, worldY));
    
            CCTileGidAndFlags info = layer.TileGIDAndFlags(tileAtXy.Column, tileAtXy.Row);
    
            if (info != null && info.Gid == 68)
            {
                Dictionary<string, string> properties = null;
    
                try
                {
                    properties = tileMap.TilePropertiesForTileID(info.Gid);
                }
                catch
                {
                    // CocosSharp 
                }
    
                if (properties != null && properties.ContainsKey("IsTreasure") && properties["IsTreasure"] == "true")
                {
                    //test adding entity via tileMap
                    reliefLayer.AddChild(new Tree(tileAtXy), 3);
                }
            }
        }
    

    Then I replaced the function given by Cocossharp library by this function :

    public Dictionary<string, string> TilePropertiesForTileID(short tileGid)
        {
            Dictionary<string, string> propertiesDict = new Dictionary<string, string>();
    
            try
            {
                // Loading from a file, you can also load from a stream
                var xmlDoc = XDocument.Load(Settings.TileMapStream);
    
                // Query the data and write out a subset of contacts
                var propertiesQuery = xmlDoc.Root.Descendants("tile")
                                            .Where(item => (int)item.Attribute("id") == tileGid)
                                            .SelectMany(a => a.Descendants("property"))
                                            .Select(property => new
                                            {
                                                Name = property.Attribute("name").Value,
                                                Value = property.Attribute("value").Value
                                            })
                                            .ToList();
    
                foreach (var property in propertiesQuery)
                {
                    Console.WriteLine($"Property Name: {property.Name}, Value: {property.Value}");
                    propertiesDict.Add(property.Name, property.Value);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
    
    
            return propertiesDict;
        }