0

I was working line by line in the debugger option (red dot) in express 2010 visual c#. This loop was assiging creatures[2].sprite.position and creatures[3].sprite.position to the same vector (100,320) at the same instance, when i equaled 2.

Further testing showed that when i = 3 the same would happen, then on i = 4, all 2,3, and 4 were changed at the same time to the same vector.

any suggestions on whats causing this, it feels like a bug, thinking about it now, I should try a different variable than i, maybe its being used some where else.

public class GameImages
    {
        //Image Diminsions
        public Texture2D texture;
        //Images position on the Viewport
        public Vector2 position = new Vector2(0,0);
        //Color
        public Microsoft.Xna.Framework.Color color = Microsoft.Xna.Framework.Color.White;
    }

 public class CreaturesAttributes
    {
        //Image
        public GameImages sprite;
        //Level
        public double Level;
    }

CreaturesAttributes[] creatures = new CreaturesAttributes[100];


public void LoadTeam()
    {
        int j = 0;
        for (int i = 1; i < creatures.Length; i++)
        {

            if (creatures[i].Color1 != null)
            {
                creatures[i].sprite.position = new Vector2(j, 320);
                j += 100;

            }
            else
            {
                i = creatures.Length;
            }
        }
    }
    protected override void Initialize()
    {
        for (int i = 0; i < creatures.Length; i++)
        {
            creatures[i] = new CreaturesAttributes();
            creatures[i].sprite = new GameImages();    
        }
    }

1 Answers1

2

This happens because you probably initialized all your array elements to point to a single instance:

var newCreature = new Creature(/* ... */);
for (int i = 0; i < creatures.Length; i++) {
  creatures[i] = newCreature;
}

Or perhaps you created multiple creatures, but with the same "sprite":

var defaultSprite = new Sprite(/* ... */);
for (int i = 0; i < creatures.Length; i++) {
  creatures[i] = new Creature();
  creatures[i].sprite = defaultSprite;
}

or maybe sprite or position are static fields:

static Sprite sprite;
//or
static Vector2 position;

All the above will cause all your mutations and accesses to happen to the same instance, so it looks like changing one is changing all of them (while there in reality is just a single creature/sprite/position that you're referencing from multiple places).

The solution is to ensure that the fields are not static, and make sure to create a new creature and creature.sprite for each:

// No static fields, and new instances for each index
for (int i = 0; i < creatures.Length; i++) {
  creatures[i] = new Creature();
  creatures[i].sprite = new Sprite();
}
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • I've edited in some more code, it starts at 1 because I use creature[0] for the enemy creature in the game. I didn't know about break;ing out of a for loop, I'm still really scrub at this. – Deluxe_Flame Jun 02 '14 at 23:28
  • Turns out in my code elsewhere in the program I had searched for a value, i.e. [a]. and established creature[a] = creature[0] turns out it paired the two, so I went through and gave it each of its values in a long list. Is there any easier way to do that? – Deluxe_Flame Jun 03 '14 at 02:21
  • If you want to create a new creature based on an existing one, you'd have to do a [deep copy](http://stackoverflow.com/questions/78536/deep-cloning-objects). If you want to initialize a hundred different creatures, you'd typically either do procedurally (e.g. each creature has 5 more health than the last) or through a config file. – that other guy Jun 03 '14 at 02:39