У меня проблемы со спрайтовой анимацией в XNA, которая, кажется, вызвана структурой, переданной в качестве ссылочного значения.Но я нигде не использую ключевое слово ref .По общему признанию, я C # noob, так что здесь может быть небольшая мелкая ошибка, но я не вижу этого.
Я создаю 10 муравьев или пчел и оживляю их, когда они перемещаются поэкран.У меня есть массив структур анимации, и каждый раз, когда я создаю муравья или пчелу, я отправляю ему требуемое значение массива анимации (просто [0] или [1] в это время).Глубоко внутри структуры анимации находится таймер, который используется для смены кадров.Класс ant / bee хранит структуру анимации как частную переменную.
Что я вижу, так это то, что каждый муравей или пчела использует одну и ту же анимационную структуру, ту, которую, как я думал, я передавал и копировал по значению.Поэтому во время Update (), когда я перемещаю таймер анимации для каждого муравья / пчелы, у следующего муравья / пчелы свой таймер анимации увеличивается на эту небольшую величину.Если на экране есть 1 муравей, он оживляет должным образом.2 муравья, он работает в два раза быстрее и так далее.Очевидно, не то, что я хочу.
Вот сокращенная версия кода.Как BerryPicking's ActorAnimationGroupData [] распределяется между BerryCreatures?
class BerryPicking
{
private ActorAnimationGroupData[] animations;
private BerryCreature[] creatures;
private Dictionary<string, Texture2D> creatureTextures;
private const int maxCreatures = 5;
public BerryPickingExample()
{
this.creatures = new BerryCreature[maxCreatures];
this.creatureTextures = new Dictionary<string, Texture2D>();
}
public void LoadContent()
{
// Returns data from an XML file
Reader reader = new Reader();
animations = reader.LoadAnimations();
CreateCreatures();
}
// This is called from another function I'm not including because it's not relevant to the problem.
// In it, I remove any creature that passes outside the viewport by setting its creatures[] spot to null.
// Hence the if(creatures[i] == null) test is used to recreate "dead" creatures. Inelegant, I know.
private void CreateCreatures()
{
for (int i = 0; i < creatures.Length; i++)
{
if (creatures[i] == null)
{
// In reality, the name selection is randomized
creatures[i] = new BerryCreature("ant");
// Load content and texture (which I create elsewhere)
creatures[i].LoadContent(
FindAnimation(creatures[i].Name),
creatureTextures[creatures[i].Name]);
}
}
}
private ActorAnimationGroupData FindAnimation(string animationName)
{
int yourAnimation = -1;
for (int i = 0; i < animations.Length; i++)
{
if (animations[i].name == animationName)
{
yourAnimation = i;
break;
}
}
return animations[yourAnimation];
}
public void Update(GameTime gameTime)
{
for (int i = 0; i < creatures.Length; i++)
{
creatures[i].Update(gameTime);
}
}
}
class Reader
{
public ActorAnimationGroupData[] LoadAnimations()
{
ActorAnimationGroupData[] animationGroup;
XmlReader file = new XmlTextReader(filename);
// Do loading...
// Then later
file.Close();
return animationGroup;
}
}
class BerryCreature
{
private ActorAnimation animation;
private string name;
public BerryCreature(string name)
{
this.name = name;
}
public void LoadContent(ActorAnimationGroupData animationData, Texture2D sprite)
{
animation = new ActorAnimation(animationData);
animation.LoadContent(sprite);
}
public void Update(GameTime gameTime)
{
animation.Update(gameTime);
}
}
class ActorAnimation
{
private ActorAnimationGroupData animation;
public ActorAnimation(ActorAnimationGroupData animation)
{
this.animation = animation;
}
public void LoadContent(Texture2D sprite)
{
this.sprite = sprite;
}
public void Update(GameTime gameTime)
{
animation.Update(gameTime);
}
}
struct ActorAnimationGroupData
{
// There are lots of other members of this struct, but the timer is the only one I'm worried about.
// TimerData is another struct
private TimerData timer;
public ActorAnimationGroupData()
{
timer = new TimerData(2);
}
public void Update(GameTime gameTime)
{
timer.Update(gameTime);
}
}
struct TimerData
{
public float currentTime;
public float maxTime;
public TimerData(float maxTime)
{
this.currentTime = 0;
this.maxTime = maxTime;
}
public void Update(GameTime gameTime)
{
currentTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (currentTime >= maxTime)
{
currentTime = maxTime;
}
}
}