naming each sprite in a list with a unique name

Is it possible to name each sprite in a list with a unique name so that I can identify each sprite to do various things?
`
public Energy(ContentManager contentManager, string spriteName, int x, int y, int i, string name)
{
this.sprite = contentManager.Load(spriteName);
this.energyPosX = x + (sprite.Width * i);
this.energyPosY = y;
this.typeName= name;

 drawRectangle = new Rectangle(energyPosX, energyPosY, sprite.Width / 2, sprite.Height / 2);

}`
I named each sprite with a string name + number ( this.typeName = name) but I cant access that name any where. Any suggestions?

You could use a Dictionary to identify each sprite.

1 Like

i actually found a solution just now.
I declared a
public string typeName
to each sprite and then identified it with
sprite.typeName
was easy. :slight_smile:

Texture2D’s have a Name field already built in.
You could just load them into a dictionary and query it.

  Dictionary<string, Texture2D> textureDict;

  // in LoadContent
  textureDict = new Dictionary<string, Texture2D>();
  var t = Content.Load<Texture2D>("sky");
  textureDict.Add(t.Name, t);

  // in draw...
  spriteBatch.Draw( textureDict["sky"], ... ect .... );

You can use a list as well with a predicate i guess but meh…

You can load everything from say a sub directory like Content/images.

            Dictionary<string, Texture2D> textureDict = new Dictionary<string, Texture2D>();
            //
            // Say you placed all your textures into the same folder.
            // string path = (Content.RootDirectory += @"/images/");
            //
            Console.WriteLine("\n  enviroment path " + Environment.CurrentDirectory);
            string path = (Content.RootDirectory);
            Console.WriteLine("\n  path " + path);
            
            //
            // using System.IO can help specifically the Path and Directory classes.
            //
            string[] filesInFolder = Directory.GetFiles(path);

            int i = 0;
            while (i < filesInFolder.Length)
            {
                filesInFolder[i] = Path.GetFileNameWithoutExtension(filesInFolder[i]);
                Console.WriteLine("\n   filesInFolder[" + i + "] : " + filesInFolder[i]);
                // textures have a Name field.
                var t = Content.Load<Texture2D>(filesInFolder[i]);
                Console.WriteLine("    t.name : " + t.Name + "  t.ToString() : "+ t.ToString());
                //
                textureDict.Add(t.Name, t);
                // next file
                i++;
            }

            // safe way to query
            Texture2D temp;
            if (textureDict.TryGetValue("skyimage ", out temp))
            {
                Console.WriteLine("\n we found a skyimage \n " + temp);
            }
            else
            {
                Console.WriteLine("\n we could not find a skyimage, we must not of loaded it :( \n ");
                // load up a dot texture , throw a debug assert
            }
            // or
            temp = textureDict["sky"];

The name field of a sprite takes the name of the image that we load. What I want is to give it a name I want.

For instance I have an energy class from which i build 10 energy cells and give each a name of

“energy1”, “energy2” etc. In the for loop that builds.

A Gun Temperature control i build with the same class I give the name

“temp1”, “temp2” etc.

This way I can find any cell with a short name. But the sprite.Name which is inbuilt if using the same sprite gives the same name.

Can I give it a name of my choice like I did with my code above? How do I do sprite.Name get and set?

There are lots of ways you could do it.

Though you can do it with lists. Dictionarys are more suited to strings as they map its hash.

define a sprite class

public class Sprite
{
    public int x;
    public int y;
    public string nickName;
    public Texture2D texture;
    public Sprite(string nickname, Texture2D t)
    {
        this.nickName = nickname;
        this.texture = t;
    }
    public Sprite(string nickname, Texture2D t, int x, int y)
    {
        this.nickName = nickname;
        this.texture = t;
        this.x = x;
        this.y = y;
    }
    public override string ToString()
    {
        return "Sprite{NickName: "+ nickName + " FileName: " + texture.Name + " Position X: " + x + " Y: " + y +"}";
    }
}

Create a class that uses dictonarys of dictionary’s to do what you want.

public class SpriteContainer
{
    Microsoft.Xna.Framework.Content.ContentManager content;
    Dictionary<string, Dictionary<string, Sprite>> typeItems = new Dictionary<string, Dictionary<string, Sprite>>();
    
    // construct 
    public SpriteContainer(Microsoft.Xna.Framework.Content.ContentManager content)
    {
        this.content = content;
    }

    // load and overload
    public void Load(string fileName, string typeName, string nickName)
    {
        Load(fileName, typeName, nickName, 0, 0);
    }

    public void Load(string fileName, string typeName, string nickName, int x, int y)
    {
        if(content == null) { Console.WriteLine("you forgot to pass in content to the constructor");  }

        var texture = content.Load<Texture2D>(fileName);

        if (typeItems.ContainsKey(typeName))
        {
            typeItems[typeName].Add(nickName, new Sprite(nickName, texture, x, y) );
        }
        else
        {
            Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();
            sprites.Add(nickName, new Sprite(nickName, texture, x, y) );
            typeItems.Add(typeName, sprites);
        }
    }

    // get
    public Sprite GetSprite(string typeName, string nickName)
    {
        return typeItems[typeName][nickName];
    }

    public Texture2D GetSpriteTexture(string typeName, string nickName)
    {
        return typeItems[typeName][nickName].texture;
    }

    // set
    public void SetSprites_Xy(string typeName, string nickName, int x, int y)
    {
        typeItems[typeName][nickName].x = x;
        typeItems[typeName][nickName].y = y;
    }

}

usage

    SpriteContainer sc;
    // setup in load
    sc = new SpriteContainer(Content);
    sc.Load("littleTexture", "energy", "energy1");

use were ever

    // set
    sc.SetSprites_Xy("energy", "energy1", 1, 10);
    // get
    var texture = sc.GetSprite("energy", "energy1").texture;
    // spriteBatch.Draw(sc.GetSpriteTexture("energy", "energy1") , ... , ... );

Edit saw a booboo

To handle the “unique” part, you can append a GUID at loadcontent time, or a “simpler way”: read the creation date of the file in a customcontentprocessor, (or at loadcontent time too but it could be very slow) and append it to a string like:
string name = myassetspritename_20171208_1056;
and add it to the tag property.

If it is only for debug purposes, just adding a counter to the name of the asset and storing it in your ‘public string typeName’ should be enough (and storing it in a dictionary as key to be sure it is unique while loading content or either method to store a list of string and search existence, then the dictionary/list/etc can be disposed after the loadcontent has finished)